Skip to content

Getting Started ​

This guide takes you from an empty namespace to your first Smell. It needs a Kubernetes cluster, kubectl, and Helm 3.8 or newer (for OCI registry support).

Install ​

KubePattern is packaged as an OCI Helm chart on the GitHub Container Registry. The chart installs the Pattern and Smell CRDs, the RBAC the analyzer needs, and the analyzer itself as a CronJob.

bash
helm upgrade --install kubepattern oci://ghcr.io/kubepattern/charts/kubepattern \
   --version <VERSION> \
   --namespace kubepattern-system \
   --create-namespace

Replace <VERSION> with the chart version you want to install. The available versions are listed on Artifact Hub.

Customize the schedule

The analysis runs every hour by default. Override it with a cron expression:

bash
--set schedule="*/30 * * * *"

Apply your first pattern ​

A Pattern is a custom resource. This one flags every PostgreSQL cluster managed by CloudNativePG that has no ScheduledBackup in its namespace:

yaml
# backup-missing.yaml
apiVersion: kubepattern.dev/v1
kind: Pattern
metadata:
  name: cnpg-cluster-without-scheduledbackup
spec:
  displayName: PostgreSQL Cluster Without Scheduled Backup
  category: Reliability
  severity: HIGH
  message: "Cluster {{target.metadata.namespace}}/{{target.metadata.name}} has no ScheduledBackup."
  target:
    kind: Cluster
    apiVersion: postgresql.cnpg.io/v1
    plural: clusters
  dependencies:
    - id: schedule
      kind: ScheduledBackup
      apiVersion: postgresql.cnpg.io/v1
      plural: scheduledbackups
  relationships:
    matchNone:
      - with: schedule
        type: custom
        criteria:
          - targetPath: "metadata.name"
            dependencyPath: "spec.cluster.name"
            operator: EQUALS
          - targetPath: "metadata.namespace"
            dependencyPath: "metadata.namespace"
            operator: EQUALS
bash
kubectl apply -f backup-missing.yaml

You do not need CloudNativePG to try KubePattern. Any kinds that exist in your cluster work, and the Registry has more patterns to start from. If a pattern names a kind that is not installed, that pattern is skipped with a warning and the others still run.

Run a scan ​

You do not have to wait for the schedule. Start a run from the CronJob right away:

bash
kubectl create job --from=cronjob/kubepattern-cronjob kubepattern-manual \
  --namespace kubepattern-system

kubectl logs job/kubepattern-manual --namespace kubepattern-system

The CronJob is named <release>-cronjob, so with the release name used above it is kubepattern-cronjob.

Read the results ​

Each finding is a Smell resource. By default it is stored in the namespace of the resource it concerns.

bash
# every smell in the cluster
kubectl get smells -A

# one smell in detail
kubectl describe smell <smell-name> -n <namespace>

Smells describes every field. When you fix the underlying problem, the Smell disappears on the next run.

Hold back transient findings ​

Not in a tagged release yet

The features below are on the main branch and arrive with the next release. The latest tagged release at the time of writing is v0.0.6, which ignores for and does not set a phase.

A resource can look unused for a few minutes while a GitOps tool re-creates its only referrer. Add a minimum duration to the pattern and the Smell stays Pending until the condition has held that long:

yaml
spec:
  for: 10m

Then keep only the findings that have persisted:

bash
kubectl get smells -A -l kubepattern.dev/phase=Active

Lifecycle explains how for, the phase and spec.since work, and how long to make the duration. To use them before the release, see Try unreleased features.

Try unreleased features ​

Some features are on the main branch but not in a tagged release yet:

  • stateful findings (for, phases and spec.since), per-pattern pruning, absence patterns and the configurable rate limit, marked next release;
  • the new constructs of the Pattern language, listed at the top of that page.

No image is built from main. The dev image is rebuilt at every push to dev, the branch that main is merged from, so it has them all. Install the chart from a checkout of the repository with that image:

bash
git clone https://github.com/kubepattern/kubepattern && cd kubepattern
helm upgrade --install kubepattern ./charts/kubepattern \
   --namespace kubepattern-system --create-namespace \
   --set image.tag=dev --set image.pullPolicy=Always

Upgrading the CRDs

Helm installs the CRDs of the chart but does not upgrade them. When you move an existing installation to a newer version, apply them again from the checkout:

bash
kubectl apply -f charts/kubepattern/crds/

Configure ​

The chart values you will use most:

ValueDefaultWhat it does
schedule"0 * * * *"Cron expression of the scan.
suspendfalseSuspends the CronJob without uninstalling.
analysis.saveInNamespacetrueStores each Smell in the namespace of its target. When false, every Smell goes to analysis.targetNamespace.
analysis.targetNamespacerelease namespaceWhere Smells go for cluster-scoped targets, or for all of them when saveInNamespace is false. The namespace must already exist.
analysis.client.qps / burst next release50 / 100Client-side rate limit of the Kubernetes API client.
RBAC.rulesread everythingThe rules the analyzer may use to read your cluster. Narrow them to the kinds your patterns need.
example.enabledtrueInstalls an example pattern, so that the first run has something to report.

Read access

By default the analyzer may get, list and watch every resource, so that any pattern you write can work. If that is more than you want, narrow RBAC.rules. A pattern whose kinds the analyzer cannot read is skipped with a warning, and the other patterns still run.

About the author ​

This project was created and is currently maintained by Gabriele Groppo (@GabrieleGroppo) as part of a Bachelor's Thesis project. The research behind it is carried out with Francesca Arcelli Fontana at the University of Milano-Bicocca.