Smells
The results of a KubePattern analysis are Smells: custom resources that each describe one defect on one resource. A Smell is produced by a Pattern, and it is kept up to date by every run until the defect is fixed.
apiVersion: kubepattern.dev/v1
kind: Smell
metadata:
name: cnpg-cluster-without-scheduledbackup-9c1e4d2a-5b7f-4c1e-8a3d-2f6b0e91c7a4
namespace: orders
spec:
name: cnpg-cluster-without-scheduledbackup
category: Reliability
severity: HIGH
message: "Cluster orders/pg-orders has no ScheduledBackup."
suppress: false
pattern:
name: cnpg-cluster-without-scheduledbackup
version: kubepattern.dev/v1
target:
apiVersion: postgresql.cnpg.io/v1
kind: Cluster
name: pg-orders
namespace: orders
uid: 9c1e4d2a-5b7f-4c1e-8a3d-2f6b0e91c7a4Retrieving results
Smells are namespaced resources, and smell is also the short name.
# every smell in the cluster
kubectl get smells -A
# one smell in detail
kubectl describe smell <smell-name> -n <namespace>
# as YAML
kubectl get smell <smell-name> -n <namespace> -o yaml
# the smells of one pattern, using its UID
kubectl get smells -A -l kubepattern.dev/pattern-uid=<pattern-uid>Patterns, in contrast, are cluster-scoped: kubectl get patterns needs no namespace.
Filtering by field
kubectl --field-selector does not work on custom resource fields such as spec.severity. Use labels, or output to JSON and filter with jq:
kubectl get smells -A -o json \
| jq -r '.items[] | select(.spec.severity=="HIGH") | .metadata.namespace + "/" + .metadata.name'Columns
kubectl get smells shows the following columns. The last three appear with -o wide.
| Column | Field | |
|---|---|---|
| Severity | spec.severity | |
| Phase next release | spec.phase | |
| Since next release | spec.since | shown as an age, such as 3d |
| Target Kind | spec.target.kind | |
| Target Name | spec.target.name | |
| Target Namespace | spec.target.namespace | -o wide |
| Message | spec.message | -o wide |
| Suppressed | spec.suppress | -o wide |
Where a Smell is stored
By default, a Smell is stored in the namespace of the resource it concerns. Smells about cluster-scoped resources, or all Smells if so configured, go to a dedicated namespace. Set analysis.saveInNamespace and analysis.targetNamespace in the chart to choose. See Getting Started.
Naming and identity
The name of a Smell is <pattern-name>-<target-uid>. The same finding is therefore updated in place across runs instead of being created again, and kubectl get smells -A always lists the current problems.
A Smell raised by an absence pattern, which has no target resource, is named <pattern-name>-empty.
The Smell resource
| Property | Description |
|---|---|
apiVersion | kubepattern.dev/v1. |
kind | Always Smell. |
metadata.name | <pattern-name>-<target-uid>. |
metadata.namespace | The namespace of the target, unless configured otherwise. |
metadata.labels | kubepattern.dev/pattern-uid next release links the Smell to its pattern. kubepattern.dev/phase next release mirrors spec.phase, so a selector can keep only Active smells. lastScan is the id of the run that last wrote it. |
spec.name | The name of the pattern that produced the Smell. |
spec.category | The category of the pattern. |
spec.severity | LOW, MEDIUM, HIGH or CRITICAL. |
spec.message | The message of the pattern, with its placeholders filled in. |
spec.reference | A link to documentation on how to fix the Smell. |
spec.pattern | The name of the pattern and its API version. |
spec.target | The apiVersion, kind, name, namespace and uid of the resource the Smell is reported on. |
spec.phase next release | Pending until the condition has held for the pattern's for, Active afterwards. |
spec.since next release | When the condition was first observed. |
spec.suppress | Whether the Smell has been marked as a false positive. |
Suppressing a false positive
A pattern can only see the references it describes, so now and then it flags something you know is fine. Mark that Smell as suppressed:
kubectl patch smell <smell-name> -n <namespace> \
--type merge -p '{"spec":{"suppress":true}}'KubePattern keeps the flag on the following runs, so the suppression survives. next release Earlier versions reset it on every update. A suppressed Smell is still listed by kubectl get smells, so filter on spec.suppress in your own dashboards and alerts.
When a Smell disappears
KubePattern removes a Smell as soon as its target no longer satisfies the pattern. Fix the problem, and the Smell is gone on the next run, with no manual clean-up. A Smell is also removed when its pattern is deleted.
If a pattern is skipped, for example because the analyzer cannot read one of its kinds, its Smells are kept rather than removed. next release Lifecycle has the details.