Installing the OpenTelemetry Operator on Kubernetes adds a controller, admission webhooks, and custom resources for managing Collectors and workload instrumentation from the Kubernetes API. It fits platform teams that want telemetry components reconciled like other cluster resources instead of maintaining hand-written Collector deployments.
The upstream static manifest installs the Operator into the opentelemetry-operator-system namespace and uses cert-manager to issue the webhook certificate. The kubectl apply path is the direct upstream install method for a cluster that already has a working kubectl context and permission to create CRDs, RBAC, namespaces, and admission webhooks.
The installation is ready when the Operator deployment is available, the opentelemetry.io API resources are listed, and a small OpenTelemetryCollector resource reconciles into a running Collector pod and service. Run the smoke-test Collector with the debug exporter only long enough to confirm reconciliation because it prints telemetry fields to logs.
Steps to install the OpenTelemetry Operator on Kubernetes:
- Confirm the active kubectl context points to the target cluster.
$ kubectl config current-context production-platform
The Operator manifest creates cluster-scoped CRDs, webhooks, and RBAC. Use a non-production cluster first when testing the install path.
- Install cert-manager from the official static manifest.
$ kubectl apply -f https://github.com/cert-manager/cert-manager/releases/download/v1.20.2/cert-manager.yaml namespace/cert-manager created customresourcedefinition.apiextensions.k8s.io/challenges.acme.cert-manager.io created customresourcedefinition.apiextensions.k8s.io/orders.acme.cert-manager.io created customresourcedefinition.apiextensions.k8s.io/certificaterequests.cert-manager.io created customresourcedefinition.apiextensions.k8s.io/certificates.cert-manager.io created ##### snipped ##### deployment.apps/cert-manager-cainjector created deployment.apps/cert-manager created deployment.apps/cert-manager-webhook created mutatingwebhookconfiguration.admissionregistration.k8s.io/cert-manager-webhook created validatingwebhookconfiguration.admissionregistration.k8s.io/cert-manager-webhook created
cert-manager provides the certificate used by the Operator admission webhook. Use the version from the current cert-manager installation documentation when a newer release is required by the cluster policy.
- Wait for cert-manager deployments.
$ kubectl wait --for=condition=Available --timeout=180s deployment --all -n cert-manager deployment.apps/cert-manager condition met deployment.apps/cert-manager-cainjector condition met deployment.apps/cert-manager-webhook condition met
- Install the OpenTelemetry Operator manifest.
$ kubectl apply -f https://github.com/open-telemetry/opentelemetry-operator/releases/latest/download/opentelemetry-operator.yaml namespace/opentelemetry-operator-system created customresourcedefinition.apiextensions.k8s.io/instrumentations.opentelemetry.io created customresourcedefinition.apiextensions.k8s.io/opampbridges.opentelemetry.io created customresourcedefinition.apiextensions.k8s.io/opentelemetrycollectors.opentelemetry.io created customresourcedefinition.apiextensions.k8s.io/targetallocators.opentelemetry.io created ##### snipped ##### deployment.apps/opentelemetry-operator-controller-manager created certificate.cert-manager.io/opentelemetry-operator-serving-cert created issuer.cert-manager.io/opentelemetry-operator-selfsigned-issuer created mutatingwebhookconfiguration.admissionregistration.k8s.io/opentelemetry-operator-mutating-webhook-configuration created validatingwebhookconfiguration.admissionregistration.k8s.io/opentelemetry-operator-validating-webhook-configuration created
- Wait for the Operator deployment.
$ kubectl wait --for=condition=Available --timeout=180s deployment/opentelemetry-operator-controller-manager -n opentelemetry-operator-system deployment.apps/opentelemetry-operator-controller-manager condition met
- Check the Operator pod.
$ kubectl get pods -n opentelemetry-operator-system NAME READY STATUS RESTARTS AGE opentelemetry-operator-controller-manager-845b44c6c7-9sc4t 1/1 Running 0 100s
- Confirm the opentelemetry.io API resources are registered.
$ kubectl api-resources --api-group opentelemetry.io NAME SHORTNAMES APIVERSION NAMESPACED KIND instrumentations otelinst,otelinsts opentelemetry.io/v1alpha1 true Instrumentation opampbridges opentelemetry.io/v1alpha1 true OpAMPBridge opentelemetrycollectors otelcol,otelcols opentelemetry.io/v1beta1 true OpenTelemetryCollector targetallocators opentelemetry.io/v1alpha1 true TargetAllocator
- Create a namespace for a reconciliation smoke test.
$ kubectl create namespace observability namespace/observability created
- Create a minimal Operator-managed Collector.
$ kubectl apply -n observability -f - <<'EOF' apiVersion: opentelemetry.io/v1beta1 kind: OpenTelemetryCollector metadata: name: smoke spec: config: receivers: otlp: protocols: grpc: endpoint: 0.0.0.0:4317 http: endpoint: 0.0.0.0:4318 processors: memory_limiter: check_interval: 1s limit_percentage: 75 spike_limit_percentage: 15 exporters: debug: verbosity: basic service: pipelines: traces: receivers: [otlp] processors: [memory_limiter] exporters: [debug] EOF opentelemetrycollector.opentelemetry.io/smoke createdThe OpenTelemetryCollector custom resource stores Collector YAML under spec.config. Generate a production Collector config separately and replace debug with the backend exporter used by the environment.
Related: How to configure an OTLP receiver in the OpenTelemetry Collector
Tool: OpenTelemetry Collector Config Generator - Wait for the Operator-managed Collector deployment.
$ kubectl rollout status deployment/smoke-collector -n observability --timeout=240s Waiting for deployment "smoke-collector" rollout to finish: 0 of 1 updated replicas are available... deployment "smoke-collector" successfully rolled out
- Check the Collector custom resource status.
$ kubectl get opentelemetrycollector smoke -n observability NAME MODE VERSION READY AGE IMAGE MANAGEMENT smoke deployment 0.153.0 1/1 76s ghcr.io/open-telemetry/opentelemetry-collector-releases/opentelemetry-collector:0.153.0 managed
The exact Collector version follows the installed Operator release unless spec.image overrides it.
- Check the Collector pod and services.
$ kubectl get pods,svc -l app.kubernetes.io/instance=observability.smoke -n observability NAME READY STATUS RESTARTS AGE pod/smoke-collector-78b9df6c86-k95lm 1/1 Running 0 76s NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE service/smoke-collector ClusterIP 10.43.57.27 <none> 4317/TCP,4318/TCP 76s service/smoke-collector-headless ClusterIP None <none> 4317/TCP,4318/TCP 76s service/smoke-collector-monitoring ClusterIP 10.43.2.154 <none> 8888/TCP 76s
- Remove the smoke-test Collector when the install proof is complete.
$ kubectl delete opentelemetrycollector smoke -n observability opentelemetrycollector.opentelemetry.io "smoke" deleted
Deleting the smoke-test custom resource removes the Operator-managed Collector objects. Do not delete production OpenTelemetryCollector resources unless their telemetry path has already been replaced.
Mohd Shakir Zakaria is a cloud architect with deep roots in software development and open-source advocacy. Certified in AWS, Red Hat, VMware, ITIL, and Linux, he specializes in designing and managing robust cloud and on-premises infrastructures.