Deploying the Elastic Distribution of OpenTelemetry (EDOT) Collector on Kubernetes sends cluster metrics, node metrics, container logs, and application telemetry to Elastic Observability through the OpenTelemetry kube-stack Helm chart. It fits clusters where workloads already use OpenTelemetry or where the OpenTelemetry Operator will inject Elastic-supported instrumentation into selected namespaces.
The Elastic-supported Kubernetes path installs the OpenTelemetry Operator plus three Collector roles. A cluster Collector gathers cluster-level metrics and events, a daemon Collector runs on nodes for node metrics, logs, and application telemetry, and a gateway Collector exports the processed data to Elastic.
The chart expects an elastic-secret-otel secret with elastic_endpoint and elastic_api_key keys in the opentelemetry-operator-system namespace. Use the versioned values file and chart version shown by Elastic for the target deployment, and use cert-manager in production when the operator webhook certificate should renew automatically instead of relying on the chart's self-signed certificate.
Steps to deploy the EDOT Collector on Kubernetes:
- Confirm that kubectl points to the cluster that should receive the EDOT Collector.
$ kubectl config current-context production-observability
Installing into the wrong context creates collectors, webhooks, and cluster-wide permissions in the wrong cluster.
- Add the OpenTelemetry Helm chart repository.
$ helm repo add open-telemetry https://open-telemetry.github.io/opentelemetry-helm-charts --force-update "open-telemetry" has been added to your repositories
- Create the operator namespace.
$ kubectl create namespace opentelemetry-operator-system namespace/opentelemetry-operator-system created
- Set a restrictive file mode for the temporary credential file.
$ umask 077
- Save the Elastic endpoint and API key in a temporary local env file.
$ cat > elastic-otel.env <<'EOF' elastic_endpoint=https://elastic.example.com:443 elastic_api_key=REDACTED_API_KEY EOF
Keep the real API key out of saved transcripts, tickets, screenshots, and shared shell history.
- Create the secret required by the Elastic EDOT values file.
$ kubectl create secret generic elastic-secret-otel \ --namespace opentelemetry-operator-system \ --from-env-file=elastic-otel.env secret/elastic-secret-otel created
The rendered EDOT gateway Collector reads ELASTIC_API_KEY from elastic_api_key and ELASTIC_ENDPOINT from elastic_endpoint in this secret.
- Remove the temporary credential file after Kubernetes stores the secret.
$ rm elastic-otel.env
- Install the OpenTelemetry kube-stack chart with the Elastic EDOT values file.
$ helm upgrade --install opentelemetry-kube-stack open-telemetry/opentelemetry-kube-stack \ --namespace opentelemetry-operator-system \ --values https://raw.githubusercontent.com/elastic/elastic-agent/refs/tags/v9.4.2/deploy/helm/edot-collector/kube-stack/values.yaml \ --version 0.12.4 Release "opentelemetry-kube-stack" does not exist. Installing it now. NAME: opentelemetry-kube-stack NAMESPACE: opentelemetry-operator-system STATUS: deployed REVISION: 1
Replace the values URL and chart version when Elastic's Add Data screen or compatibility notes show a different pair for the target Stack version.
- Check the Helm release state.
$ helm status opentelemetry-kube-stack --namespace opentelemetry-operator-system NAME: opentelemetry-kube-stack NAMESPACE: opentelemetry-operator-system STATUS: deployed REVISION: 1 ##### snipped #####
- Verify that the operator and Collector pods are running.
$ kubectl get pods --namespace opentelemetry-operator-system NAME READY STATUS RESTARTS AGE opentelemetry-kube-stack-opentelemetry-operator-6f6dbb9b7c-nx7dk 2/2 Running 0 4m opentelemetry-kube-stack-cluster-stats-collector-74dddc8f6-s5msx 1/1 Running 0 3m opentelemetry-kube-stack-daemon-collector-8jfq2 1/1 Running 0 3m opentelemetry-kube-stack-daemon-collector-zlq6p 1/1 Running 0 3m opentelemetry-kube-stack-gateway-collector-7db8dd6df5-5szbn 1/1 Running 0 3m
The daemon Collector has one pod per scheduled node, so the exact count should match the node placement in the cluster.
- Check the gateway Collector startup log.
$ kubectl logs deployment/opentelemetry-kube-stack-gateway-collector \ --namespace opentelemetry-operator-system 2026-06-18T10:16:31.014Z info service@v0.138.0/service.go:199 Starting otelcol 2026-06-18T10:16:31.275Z info otlpreceiver@v0.138.0/otlp.go:116 Starting GRPC server {"endpoint": "0.0.0.0:4317"} 2026-06-18T10:16:31.276Z info otlpreceiver@v0.138.0/otlp.go:173 Starting HTTP server {"endpoint": "0.0.0.0:4318"} 2026-06-18T10:16:31.318Z info service@v0.138.0/service.go:225 Everything is ready. Begin running and processing data.Authentication or endpoint errors usually appear in the gateway Collector because that role exports data to Elastic.
- Annotate an application namespace when EDOT auto-instrumentation is needed for workload traces.
$ kubectl annotate namespace apps instrumentation.opentelemetry.io/inject-nodejs="opentelemetry-operator-system/elastic-instrumentation" --overwrite namespace/apps annotated
Use nodejs, java, python, dotnet, or go as supported by the workload, then restart the application pods so the instrumentation is injected.
- Confirm Kubernetes telemetry in Elastic Observability. Open Kibana, go to Dashboards, and search for [OTEL][Metrics Kubernetes] Cluster Overview.
The dashboard should show the cluster, nodes, namespaces, pods, and recent metrics from the deployed Collectors.
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.