Writing Rules
Korrel8r comes with a comprehensive set of rules for correlating Kubernetes resources and observability signals. You can add your own rules to handle custom relationships – for example, correlating a custom resource with its logs or metrics.
Rules are defined in YAML files and loaded from the configuration.
Rule Structure
A rule defines a relationship between a set of start classes and a set of goal classes. It contains a Go template that takes a start object and generates a query for the goal class.
rules:
- name: MyRuleName
start:
domain: source-domain
classes:
- SourceClass
goal:
domain: target-domain
classes:
- TargetClass
result:
query: |-
target-domain:TargetClass:query-details-template
- name: identifies the rule in graphs and log output.
- start: the domain and classes this rule applies to. Omitting
classesmeans all classes in the domain. - goal: the domain and classes the rule produces queries for.
- result.query: a Go template that receives a start object and outputs a goal query string.
Example: Kubernetes Selector to Pods
This rule from etc/korrel8r/rules/k8s.yaml finds Pods owned by resources that use label selectors
(Deployments, Services, ReplicaSets, etc.):
aliases:
- name: selectors
domain: k8s
classes:
- Service
- Deployment.apps
- ReplicaSet.apps
- StatefulSet.apps
rules:
- name: SelectorToPods
start:
domain: k8s
classes: [selectors]
goal:
domain: k8s
classes: [Pod]
result:
query: |-
k8s:Pod:{"namespace": "{{.metadata.namespace}}"
{{- with .spec.selector.matchLabels}}, "labels": {{mustToJson . -}}{{end -}} }
How it works:
- The rule applies to any object in the
selectorsalias (Deployments, Services, etc.) - The template extracts the namespace and label selector from the start object.
- It generates a
k8s:Podquery that finds Pods matching those labels.
For example, given a Deployment in namespace myapp with selector app=web, the template produces:
k8s:Pod:{"namespace": "myapp", "labels": {"app":"web"}}
Example: Kubernetes Resources to Metrics
This rule finds Prometheus metrics related to any Kubernetes resource:
rules:
- name: AllToMetric
start:
domain: k8s
goal:
domain: metric
result:
query: |-
metric:metric:{namespace="{{.metadata.namespace}}",{{lower .kind}}="{{.metadata.name}}"}
Since start has no classes field, this rule applies to all classes in the k8s domain.
The lower function converts the Kind (e.g. “Pod”) to lowercase for the PromQL label name.
Template Basics
Rule templates use Go template syntax.
The template receives the start object as its context (.), so you can access fields directly.
Korrel8r includes the Sprig template function library. Some domains provide additional functions – see the Domain Reference and Configuration Reference for details.
Common patterns:
| Pattern | Description |
|---|---|
{{.metadata.namespace}} |
Access a field on the start object |
{{.metadata.name}} |
Access another field |
{{with .field}}...{{end}} |
Conditionally include a section if the field exists |
{{range .items}}...{{end}} |
Iterate over a list |
{{mustToJson .field}} |
Convert a value to JSON |
{{lower .kind}} |
Convert to lowercase |
If a template returns a blank string or raises an error, korrel8r skips the rule for that object. Errors are logged, blanks are ignored silently.
Adding a Rule
-
Choose or create a YAML file in
etc/korrel8r/rules/. Files are organized by domain:k8s.yaml,log.yaml,alert.yaml, etc. If you add a new file, include it inall.yamlto have it picked up by default configurations. -
Add your rule to the
ruleslist in the file. -
If you want to contribute your rule to the project, add a test case in the corresponding
*_test.gofile.