Skip to content

KollectTarget

Scope: Namespace · Reconciled: Yes · Short name: ktgt

Same-namespace profileRef

spec.profileRef must name a KollectProfile in the same namespace as the target. Platform cross-namespace collection uses KollectClusterTarget instead.

What it is for

A KollectTarget binds a KollectProfile to which resources to watch: workload namespaces, label selectors, explicit names, and watch-mode policy. The target controller registers a shared informer for the profile GVK (one per GVK cluster-wide) and filters events per target selectors.

This is the default team-scoped collection object. Platform cross-namespace collection uses KollectClusterTarget instead.

See ADR-0301, ADR-0205, ADR-0207.

How it fits the pipeline

flowchart LR
  Profile[KollectProfile]
  Scope[KollectScope]
  Target[KollectTarget]
  Inv[KollectInventory]
  API[(Kubernetes API)]

  Profile -->|"profileRef"| Target
  Scope -.->|GVK + NS policy| Target
  Target -->|informer watch| API
  Target -->|rows| Inv
Relationship Rule
Profile spec.profileRef — same namespace, required
Scope Optional; when present enforces GVK and workload namespaces
Inventory All targets in namespace aggregate into KollectInventory
Sink Target status reflects namespace sink reachability for export path

Collection diagram: DATA-FLOWS.md §2.

Spec fields

Field Type Required Description
spec.profileRef string Yes KollectProfile name in same namespace
spec.namespaceSelector labelSelector No Restrict collected workload namespaces
spec.includedNamespaces[] list No Static namespace allowlist (AND with selector)
spec.excludedNamespaces[] list No Static namespace denylist
spec.namespaceExcludeSelector labelSelector No Label-based namespace exclude
spec.resourceRules[] list No GVK + label/CEL rules (OR union); empty → legacy selectors
spec.labelSelector labelSelector No Legacy resource label filter when resourceRules empty
spec.names[] list No Explicit resource names
spec.suspend bool No Pause reconciliation
spec.watchMode enum No All (default) or OptIn — see watch labels

Example

A target that binds the deployment-images profile to workloads labelled app.kubernetes.io/name=nginx (config/samples/kollect_v1alpha1_kollecttarget.yaml):

apiVersion: kollect.dev/v1alpha1
kind: KollectTarget
metadata:
  name: nginx-deployments
  namespace: default
spec:
  profileRef: deployment-images
  labelSelector:
    matchLabels:
      app.kubernetes.io/name: nginx
  suspend: false

Opt-in watch and Argo/Helm targets live alongside it in config/samples/ (*_kollecttarget_opt-in.yaml, *_argo-applications.yaml, *_helm-releases.yaml).

Sample usage

Basic Deployment collection:

kubectl apply -f config/samples/kollect_v1alpha1_kollectprofile.yaml
kubectl apply -f config/samples/kollect_v1alpha1_kollecttarget.yaml

# Optional workload
kubectl create deployment nginx --image=nginx:1.27
kubectl label deployment nginx app.kubernetes.io/name=nginx --overwrite

kubectl get ktgt -n default nginx-deployments -w
kubectl describe ktgt nginx-deployments -n default

Opt-in watch mode (only kollect.dev/watch: enabled):

kubectl apply -f config/samples/kollect_v1alpha1_kollecttarget_opt-in.yaml

Argo CD Applications:

kubectl apply -f config/samples/kollect_v1alpha1_kollectprofile_argo-application-summary.yaml
kubectl apply -f config/samples/kollect_v1alpha1_kollecttarget_argo-applications.yaml

Helm releases (Flux):

kubectl apply -f config/samples/kollect_v1alpha1_kollectprofile_helm-release-summary.yaml
kubectl apply -f config/samples/kollect_v1alpha1_kollecttarget_helm-releases.yaml

Status conditions

Type When set Meaning Remediation
Ready=True Collecting Profile resolved; informer registered None
Synced=True Healthy reason: Collecting with item count Monitor status message
Degraded=True Blocked See reason below Fix root cause; generation bump re-reconciles
SinkReachable=True/False Export path Namespace inventory family sinks reachable Fix KollectSnapshotSink, KollectDatabaseSink, or KollectEventSink connection

Common Degraded reasons

Reason Cause Fix
Suspended spec.suspend: true Set suspend: false
MissingProfileRef Empty profileRef Set valid profile name
ProfileNotFound No matching profile kubectl apply profile in same namespace
ScopeGVKDenied GVK not allowed Update KollectScope allowedGVKs
ScopeNamespaceDenied Workload NS blocked Add namespace to allowedNamespaces
ScopeLookupFailed API error loading scope Check RBAC; apiserver health
InformerRegistrationFailed Dynamic client / GVK error Verify CRD installed; check operator logs
Forbidden SAR denied list in scoped NS Grant operator read on target GVK in workload namespaces
SinkNotFound / SinkUnreachable Inventory sink broken Fix sink CR and connection test

RBAC

Actor Verbs Resource Notes
Team engineers get, list, watch, create, update, patch, delete kollecttargets Tenant namespace
Operator get, list, watch kollecttargets, kollectprofiles, kollectscopes, kollectsnapshotsinks, kollectdatabasesinks, kollecteventsinks Reconcile
Operator get, list, watch Target GVK resources Dynamic — per profile (e.g. deployments)
Operator update, patch kollecttargets/status Write conditions

In tenant mode, Helm restricts the operator to watchNamespaces; targets still need SAR success for each workload namespace they scrape.

Common failure modes

Symptom Likely cause Fix
itemCount stays 0 Label selector mismatch kubectl get deploy -l app.kubernetes.io/name=nginx
Namespace skipped Watch label / annotation See ADR-0205; check kollect.dev/watch
Forbidden partial collection RBAC too narrow Extend ClusterRole or use namespace-scoped RoleBindings
Target in wrong namespace Namespaced kind kubectl get ktgt -A; match profile namespace
No reconcile after profile edit Secondary watch pending Bump target generation or wait for beta watch
OptIn collects nothing Missing enabled label Label namespace or resource kollect.dev/watch: enabled

See also