What is KubePattern?
KubePattern is an open-source analyzer, written in Go, that finds relational smells in Kubernetes: defects that live not in any single manifest, but in the relations between resources.
Valid in isolation, wrong together
A Page that no menu lists, a Composition for a kind that nothing defines, a database Cluster with no backup schedule. Every one of these manifests is valid on its own. The defect shows up only in the presence or the absence of a relation, which is exactly what KubePattern looks at.
Extensibility makes this matter more every year. Custom resource definitions let operators register new kinds, and entire platforms are now built out of custom resources that refer to each other by name. A growing part of a deployment's architecture is expressed through those relations (ownership, label selectors, references by name), and few tools check them.
Relational smells
KubePattern groups what it finds into four families.
| Family | What it is | Example |
|---|---|---|
| Unused / orphan | A definition exists, but nothing refers to it. | A ClusterIssuer that no Certificate uses |
| Dangling reference | A resource points at something that does not exist. | A Composition for a kind that no XRD defines |
| Missing companion | A resource lacks the sibling that should accompany it. | A PostgreSQL Cluster with no ScheduledBackup |
| Misconfiguration | A relation exists that should not. | A Pooler named like a Cluster in the same namespace |
The Pattern reference shows how a pattern describes each family, and the Registry has ready-made patterns for real platforms.
How a scan works
- Read the patterns. Patterns are custom resources in your cluster. Each one is checked by a linter before use: a malformed pattern is logged and skipped.
- Fetch what they need. Kinds are resolved at run time through API discovery and the dynamic client, so custom resources unknown at build time are reachable. Only the kinds the patterns name are listed, together with the owner kinds reachable from them. A pattern can also name a set of kinds, such as every kind of an API group or of a discovery category.
- Build the graph. The fetched resources become the vertices of a graph that is built once per run and never modified by the analysis.
- Evaluate. For each pattern, the engine selects the candidate targets and checks the relationships declared in the pattern against the graph.
- Write the smells. Each target that matches becomes a Smell, a custom resource that carries the severity, category and message of the pattern.
- Self-heal. When the condition stops holding, the Smell is deleted on the next run. Nothing needs to be cleaned up by hand.
The scan runs as a Kubernetes CronJob, hourly by default. Between scans, nothing is running.
Pattern-as-Code
A Pattern describes a defect, not a rule: it states the condition that a defective resource satisfies, so every match is a finding. Patterns are built from a small set of relational primitives and contain no expression language, which keeps them readable and checkable. The primitives follow the ways resources refer to one another: references by name, ownership, and label selectors.
The resource a smell is reported on, the target, is fixed by the pattern. A smell may arise from the interaction of several resources, but it is always attributed to one.
target:
kind: ClusterIssuer
apiVersion: cert-manager.io/v1
plural: clusterissuers
dependencies:
- id: certificate
kind: Certificate
apiVersion: cert-manager.io/v1
plural: certificates
relationships:
matchNone: # no Certificate refers to the issuer: it is unused
- with: certificate
type: custom
criteria:
- targetPath: "metadata.name"
dependencyPath: "spec.issuerRef.name"
operator: EQUALSStateful, Kubernetes-native findings
Patterns and Smells are both custom resources. You query them with kubectl, protect them with RBAC, and manage them with GitOps.
- Stable identity. A Smell is named after its pattern and the UID of its target, so the same finding is updated in place from run to run.
- First observation. Each Smell records when it was first seen (
spec.since). - Minimum duration. A pattern can require its condition to hold for a minimum time (
for) before the finding turns fromPendingtoActive. This hides transient states, such as a resource that looks unused for a few minutes while a GitOps tool re-creates its only referrer. See Lifecycle. - Suppression. Mark a false positive once and it stays suppressed on later runs.
What KubePattern is not
- Not a policy engine. KubePattern does not sit in the admission path and does not block anything. It complements engines such as Kyverno, which are the right tool for enforcement and for rich per-field rules.
- Not a cleaner. KubePattern never deletes your resources. Its service account reads the cluster and writes only its own Smells.
- Not a per-resource linter. It does not check one manifest against best practices. It checks how resources relate.
Where next
- Getting Started: install the chart and run your first scan.
- Use Cases: what teams use it for.
- Patterns, Smells and Lifecycle: the concepts in detail.