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
Discovery -- On startup the groundcover sensor and the k8s-watcher backend list every CRD installed in the cluster.
Filtering -- Each CRD is matched against the
allowedKindslist in the Helm values. Only CRDs whose Kind (case-insensitive) and API group match an entry in the list are watched.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.
Workload classification -- If the matching
allowedKindsentry hasworkload.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.Name resolution -- The workload name shown in groundcover is determined by an optional
nameFromconfig (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:
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.
Both k8sWatcher.watch.crd.allowedKinds and agent.sensor.k8sEntitiesWatch.crd.allowedKinds must contain the same entry. The sensor watches CRD instances on each node for pod-to-workload resolution, while the k8s-watcher provides cluster-wide entity tracking.
Required fields
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
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:
Labels -- Check each label key listed in
nameFrom.labelsin order. The first non-empty label value becomes the workload name.Annotations -- Check each annotation key listed in
nameFrom.annotationsin order. The first non-empty annotation value becomes the workload name.Generate name pattern -- If the instance has a
metadata.generateName, apply the regex innameFrom.generateNamePatternand use the first capture group.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-xk92jmetadata.generateName:daily-etl-metadata.labels:{"workflows.argoproj.io/cron-workflow": "daily-etl"}
Resolution proceeds as:
Check label
run-family-- not present, skip.Check label
workflows.argoproj.io/workflow-template-- not present, skip.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
