For the complete documentation index, see llms.txt. This page is also available as Markdown.

Custom resource workloads

How groundcover discovers Kubernetes Custom Resource Definitions and resolves matching instances to workloads.

By default groundcover tracks built-in Kubernetes workload types such as Deployments, StatefulSets, and DaemonSets. Many clusters also run custom resources -- for example Argo Rollouts, OpenKruise CloneSets, or Spark Applications -- that own pods the same way a Deployment does.

groundcover can watch these Custom Resource Definitions (CRDs) so that their instances appear as first-class workloads in the Workloads page, Maps, filters, and monitors.


How it works

  1. Discovery -- On startup the groundcover sensor and the k8s-watcher backend list every CRD installed in the cluster.

  2. Filtering -- Each CRD is matched against the allowedKinds list in the Helm values. Only CRDs whose Kind (case-insensitive) and API group match an entry in the list are watched.

  3. Watching -- For every matched CRD, groundcover creates a watcher that tracks create, update, and delete events for all instances of that resource across the cluster.

  4. Workload classification -- If the matching allowedKinds entry has workload.enabled: true, each instance of that CRD is classified as a workload. Pods owned by the CRD instance resolve to that workload name, and a Workload page is created in the UI.

  5. Name resolution -- The workload name shown in groundcover is determined by an optional nameFrom config (see Workload name resolution below). When no custom resolution is configured, the Kubernetes object name is used.


Default allowed kinds

groundcover ships with the following CRD kinds enabled by default:

Kind
API group
Workload
Notes

Rollout

argoproj.io

Yes

Argo Rollouts progressive delivery

CloneSet

apps.kruise.io

Yes

OpenKruise CloneSet workload controller

Workflow

argoproj.io

Yes

Argo Workflows (with custom name resolution)

SparkApplication

sparkoperator.k8s.io

No

Tracked as a CRD entity, not as a workload

Runner

actions.summerwind.dev

No

GitHub Actions self-hosted runners

Kinds marked Workload = Yes appear on the Workloads page and in workload filters. Kinds marked No are tracked for entity metadata but do not create Workload pages.

If the CRD is not installed in the cluster, the entry is silently ignored. You only need to remove an entry if you want to stop watching a CRD that is installed.


Adding a custom CRD

To watch a new CRD kind and have its instances appear as workloads, add an entry under both the k8s-watcher and sensor sections of your Helm values override:

After applying the updated Helm values, the sensor and k8s-watcher pick up the new CRD on their next restart.

Required fields

Field
Description

group

The API group of the CRD (e.g. argoproj.io). Must match exactly.

kindPlural

The plural resource name from the CRD spec (e.g. rollouts, clonesets).

workload.enabled

Set to true to classify instances as workloads. When false or omitted, instances are tracked as CRD entities but do not appear on the Workloads page.

Optional fields

Field
Description

versions

A list of specific CRD versions to watch (e.g. ["v1alpha1"]). When omitted, all served versions are watched.

workload.nameFrom

Custom workload name resolution. See below.


Workload name resolution

When workload.enabled: true, groundcover determines the workload name for each CRD instance using the following priority:

  1. Labels -- Check each label key listed in nameFrom.labels in order. The first non-empty label value becomes the workload name.

  2. Annotations -- Check each annotation key listed in nameFrom.annotations in order. The first non-empty annotation value becomes the workload name.

  3. Generate name pattern -- If the instance has a metadata.generateName, apply the regex in nameFrom.generateNamePattern and use the first capture group.

  4. Object name -- Fall back to metadata.name.

If nameFrom is not configured, the object name is always used.

Example: Argo Workflows

Argo Workflows dynamically generate workflow instance names (e.g. daily-etl-xk92j). The default configuration uses labels and generate-name patterns to group these instances under a stable workload name:

For a workflow instance with:

  • metadata.name: daily-etl-xk92j

  • metadata.generateName: daily-etl-

  • metadata.labels: {"workflows.argoproj.io/cron-workflow": "daily-etl"}

Resolution proceeds as:

  1. Check label run-family -- not present, skip.

  2. Check label workflows.argoproj.io/workflow-template -- not present, skip.

  3. Check label workflows.argoproj.io/cron-workflow -- found: daily-etl. This becomes the workload name.

If none of those labels existed, the generate-name pattern ^(.+)-$ would match daily-etl- and extract daily-etl.

If generateName was also empty, the raw object name daily-etl-xk92j would be used.


Disabling CRD watching

To stop watching all CRDs, set enabled: false:

To stop watching a specific kind, remove its entry from allowedKinds in both sections.


RBAC

groundcover automatically generates ClusterRole rules for each entry in allowedKinds, granting list, watch, and get permissions on the CRD's API group and plural resource. No manual RBAC configuration is required.

Last updated