BetaFree-to-use OpAMP fleet management for Windows & LinuxQuick Start →

Kubernetes Workload Observation

CollectorCtrl can show the OpenTelemetry Collectors you already run in Kubernetes next to your host collectors. You keep your Helm charts, GitOps controllers and deployment pipelines. A small in-cluster observer reports what is running; CollectorCtrl displays it.

Pilot feature — v0.6.0-beta

Kubernetes support is an observation pilot. It shows workload identity, observed configuration and pod instances. It does not collect collector metrics, push configuration, restart pods or upgrade workloads. Live validation on GKE, AKS, EKS and OpenShift is still in progress, so treat these platforms as validation targets rather than certified support.


How it works

Your Kubernetes cluster
Helm · GitOps · CI pipeline
Your deployment tooling, unchanged
deploys
Collector workload
Deployment / DaemonSet / StatefulSet + ConfigMap
reads via Kubernetes API (read-only)
CollectorCtrl observer
Watches CollectorMonitor resources
wss:// · OpAMP
outbound, TLS verified
CollectorCtrl server
Fleet Inventory
Host collectorsKubernetes workloads
stores snapshot
OpAMP gateway
Port 4320
Never edits workloads, ConfigMaps or pods; writes only CollectorMonitor status One CollectorMonitor per workload
  1. You install the observer (Helm chart from CollectorCtrl-K8s-Operator) once per cluster.
  2. For each collector workload you want to see, you create one CollectorMonitor resource.
  3. The observer reads the workload, its pods and its mounted ConfigMap through the Kubernetes API and sends a snapshot to CollectorCtrl over a trusted wss:// OpAMP connection.
  4. The observer only ever writes CollectorMonitor status. It never changes your workloads, ConfigMaps or application pods.

What you see in CollectorCtrl

The Fleet Inventory has three views: All, Host collectors and Kubernetes workloads. The Kubernetes view adds cluster and namespace filters. Opening a workload shows:

TabWhat it contains
ConfigurationConfigMap name and key, resource version, configuration hash and observation time. Configuration YAML appears only if reportConfig: true is set on the monitor.
InstancesDesired and ready instances, image, restarts and waiting/termination reasons per pod. Terminating pods are marked; completed pods are hidden by default. Kubernetes nodes are shown as pod placement, not as managed hosts.
Source & ownershipCluster, namespace, workload kind and name, collector container and any available ownership information.
Freshness is explicit

A snapshot that is old, or from an observer that has disconnected, is shown as historical. The freshness budget is at least two minutes, or twice the reporting interval plus thirty seconds. Kubernetes readiness is not treated as proof that the configuration is loaded at runtime or that telemetry reaches its destination.


What CollectorCtrl will not do to observed workloads

Your deployment system remains in charge. Observed Kubernetes workloads are:

  • Excluded from host configuration policies, canary rollouts, Supervisor upgrades, runtime templates and Telemetry Governor taps.
  • Protected from host-only actions. Restart, remote commands, package deployment and instrumentation are rejected for them, whether requested from the UI, the REST API, the MCP server or Copilot. Mixed bulk operations list unsupported targets instead of reporting success.
  • Not edited from CollectorCtrl. Git pull request workflows and emergency direct writes for workloads are not available in this release.

Install the observer

1

1. Prepare the CollectorCtrl server

Run a CollectorCtrl server build that matches the observer build (v0.6.0-beta or later). The OpAMP endpoint (port 4320) must be reachable from the cluster over wss:// with a certificate the observer trusts. Certificate verification cannot be turned off.

2

2. Create an enrollment token

In CollectorCtrl, go to Settings → API Tokens → Agent Enrollment and create a cce_… token. Each new workload/container identity uses one enrollment, so allow enough uses for the workloads you plan to monitor.

3

3. Store the token in a Secret

Create a Secret in the observer's namespace with the key enrollment-token, using your normal secret-management workflow.

4

4. Install the Helm chart

Install the chart from the operator repository, pointing it at your server and Secret (see the command below).

5

5. Create a CollectorMonitor per workload

Apply one CollectorMonitor for each collector workload you want to see, then open Fleet → Kubernetes workloads.

kubectl create namespace collectorctrl-system

kubectl create secret generic collectorctrl-auth \
  --namespace collectorctrl-system \
  --from-literal=enrollment-token=cce_YOUR_TOKEN

helm upgrade --install collectorctrl-observer ./helm-charts/collectorctrl-operator \
  --namespace collectorctrl-system \
  --set opamp.server=wss://collectorctrl.example.internal:4320/v1/opamp \
  --set opamp.enrollmentSecret=collectorctrl-auth

The chart pulls the published observer image, ghcr.io/collectorctrl/collectorctrl-k8s-operator/operator:latest, by default. Override image.repository and image.tag to use your own registry or a pinned build.

Keep the credential volume

After enrollment, the observer saves per-workload credentials on a retained PersistentVolumeClaim and reuses them on reconnect and restart. The chart needs a provisionable storage class, or set credentialStorage.existingClaim. Keep this claim across upgrades and reinstalls. Run exactly one observer replica (the chart uses the Recreate strategy), because multiple credential writers are not supported.

Common chart settings

ValuePurpose
opamp.serverThe trusted wss:// OpAMP endpoint. Monitors must use exactly this endpoint.
opamp.enrollmentSecretSecret holding enrollment-token.
opampCAConfigMapConfigMap with ca.crt when your server uses a private certificate authority.
credentialStorage.existingClaim / storageClassName / sizeWhere per-workload credentials are kept.
rbac.clusterScopedtrue (default) observes across namespaces; false restricts the observer to its own namespace.
clusterIDStable, unique cluster ID. Discovered from the kube-system namespace UID by default; required when rbac.clusterScoped=false.
rbac.authSecretNamesNames of per-monitor Secrets the observer may read (empty by default).

OpenShift: add -f helm-charts/collectorctrl-operator/values-openshift.yaml before your own values. This lets the cluster's SCC assign the UID and fsGroup. Do not grant anyuid or privileged to work around an install error.


Monitor an existing collector

apiVersion: collectorctrl.io/v1alpha1
kind: CollectorMonitor
metadata:
  name: existing-gateway
  namespace: observability
  labels:
    k8s.cluster.name: production-eu
spec:
  workloadSelector:
    kind: Deployment          # Deployment, DaemonSet or StatefulSet
    name: otel-gateway
    matchLabels: {}
  collectorContainer: otel-collector   # required for multi-container pods
  opampServer: wss://collectorctrl.example.internal:4320/v1/opamp
  reportConfig: false                  # opt in to upload the config YAML
  healthCheck:
    interval: 30s
  • One monitor selects exactly one workload. An ambiguous selector reports an error rather than picking one.
  • If the container mounts several ConfigMaps or YAML keys, set configMapSelector.name and configMapSelector.key.
  • Don't create two monitors for the same collector container; they would share one identity.
  • Check discovery and connection errors with kubectl describe collectormonitor existing-gateway -n observability.
Think before enabling reportConfig

With reportConfig: true, the observed configuration YAML is uploaded to CollectorCtrl. Dedicated redaction is not yet available. Leave it off for configurations that contain inline credentials, and prefer environment or Secret references.


Upgrading an existing observer

If you installed an earlier observer build:

  1. Create an Agent Enrollment token and reference it through opamp.enrollmentSecret.
  2. Make sure persistent credential storage is available, and reuse it across upgrades.
  3. Run one replica.
  4. Set opamp.server to the trusted wss:// endpoint and use the same endpoint in every monitor. Add opampCAConfigMap for a private CA.
  5. Installations that used a shared secret should first run with opamp.authMode=legacy and opamp.existingSecret (key secret-key) so credentials are issued and saved, then switch to enrollment and turn off server legacy mode.

Upgrade the server and the observer together.


Current limits

  • Discovery covers Deployments, DaemonSets and StatefulSets with a selected collector container and mounted or projected ConfigMaps. Injected sidecars without a template ConfigMap mount, native OpenTelemetry Operator resources, Secret-backed configuration and OpenShift DeploymentConfig are not covered yet.
  • Command-line config merges, environment expansion and remote config providers are not reconstructed.
  • Cluster- or namespace-specific team permissions are not implemented yet; existing permissions and environment rules still apply.
  • Old workload records need manual pruning. Deleting and recreating a workload creates a new fleet identity.
  • Observed workloads count toward the existing agent capacity allowance.

Coming next

Platform validation across Kubernetes distributions, verified Git ownership and source bindings, then validated pull-request proposals for raw ConfigMaps, the official Helm chart and OpenTelemetryCollector resources.