﻿---
title: Quickstart for Kubernetes on Elastic Cloud Hosted
description: Learn how to set up the {{agent}} and EDOT SDKs in a Kubernetes environment with Elastic Cloud Hosted to collect metrics, logs, and traces using the Managed OTLP Endpoint.
url: https://docs-v3-preview.elastic.dev/elastic/docs-content/pull/7920/solutions/observability/get-started/opentelemetry/quickstart/ech/k8s
products:
  - Elastic Agent
  - Elastic Cloud Hosted
  - Elastic Observability
applies_to:
  - Elastic Cloud Hosted: Generally available
---

# Quickstart for Kubernetes on Elastic Cloud Hosted
Learn how to set up the Elastic Agent and EDOT SDKs in a Kubernetes environment with Elastic Cloud Hosted (ECH) to collect host metrics, logs, and application traces. This quickstart uses the [Elastic Cloud Managed OTLP Endpoint](https://docs-v3-preview.elastic.dev/elastic/opentelemetry/tree/main/reference/managed-inputs/managed-otlp-endpoint) — the recommended ingestion path for ECH.

## Guided setup

Use the **Add data** screen in Elastic Observability to generate install commands that are already configured with the values you need.
1. Open Elastic Observability.
2. Go to **Add data**.
3. Select what you want to monitor.
4. Follow the instructions.


## Prerequisites

- An Elastic Cloud Hosted deployment running version 9.0 or later.
- Helm version 3.9+ up to and including 3.21.0.


## Manual installation

Follow these steps to deploy the Elastic Agent and EDOT SDKs in Kubernetes with ECH.
<stepper>
  <step title="Add the repository to Helm">
    Run the following command to add the charts repository to Helm:
    ```bash
    helm repo add open-telemetry "https://open-telemetry.github.io/opentelemetry-helm-charts" --force-update
    ```
  </step>

  <step title="Find your endpoint and create an API key">
    **Find your endpoint**
    1. Log in to the [Elastic Cloud Console](https://cloud.elastic.co/).
    2. From the home page, find your deployment in **Hosted deployments**, and select **Manage**.
    3. In the **Application endpoints, cluster and component IDs** section, select **Managed OTLP**.
    4. Copy the public endpoint value.
    **Create an API key**
    <dropdown title="Using Kibana">
      1. Go to **Stack Management** → **API keys**.
      2. Click **Create API key**, enter a name, and enable **Control security privileges**.
      3. In the role descriptors box, enter the following:
         ```json
         {
           "otlp_writer": {
             "applications": [
               {
                 "application": "apm",
                 "resources": ["*"],
                 "privileges": ["event:write"]
               }
             ]
           }
         }
         ```
      4. Click **Create API key** and copy the encoded value.
    </dropdown>

    <dropdown title="Using the Elasticsearch API">
      Use the [Create API key](https://www.elastic.co/docs/api/doc/elasticsearch/operation/operation-security-create-api-key) API:
      ```json

      {
        "name": "otlp-writer",
        "role_descriptors": {
          "otlp_writer": {
            "applications": [
              {
                "application": "apm",
                "resources": ["*"],
                "privileges": ["event:write"]
              }
            ]
          }
        }
      }
      ```
      The `event:write` privilege for the `apm` application is the minimum required to send data through the Elastic Cloud Managed OTLP Endpoint.
    </dropdown>
  </step>

  <step title="Configure your credentials">
    Replace `<ELASTIC_OTLP_ENDPOINT>` and `<ELASTIC_API_KEY>` in the following command to create a namespace and a secret with your credentials.
    ```bash
    kubectl create namespace opentelemetry-operator-system
    kubectl create secret generic elastic-secret-otel \
    --namespace opentelemetry-operator-system \
    --from-literal=elastic_otlp_endpoint='<ELASTIC_OTLP_ENDPOINT>' \
    --from-literal=elastic_api_key='<ELASTIC_API_KEY>'
    ```

    <note>
      On Windows PowerShell, replace backslashes (`\`) with backticks (```) for line continuation and single quotes (`'`) with double quotes (`"`).
    </note>
  </step>

  <step title="Install the Operator">
    Install the OpenTelemetry Operator using the `kube-stack` Helm chart with the `managed_otlp` values file:
    ```bash
    helm install opentelemetry-kube-stack open-telemetry/opentelemetry-kube-stack \
    --namespace opentelemetry-operator-system \
    --values 'https://raw.githubusercontent.com/elastic/elastic-agent/refs/tags/v9.5.1/deploy/helm/edot-collector/kube-stack/managed_otlp/values.yaml' \
    --version '0.12.4'
    ```
    The Operator provides a deployment of the Elastic Agent and configuration environment variables. This allows SDKs and instrumentation to send data to the Elastic Agent without further configuration.
  </step>

  <step title="Auto-instrument applications">
    Add a language-specific annotation to your namespace by replacing `<LANGUAGE>` with one of the supported values (`nodejs`, `java`, `python`, `dotnet`, or `go`) in the following command.
    ```bash
    kubectl annotate namespace YOUR_NAMESPACE instrumentation.opentelemetry.io/inject-<LANGUAGE>="opentelemetry-operator-system/elastic-instrumentation"
    ```
    The OpenTelemetry Operator automatically provides the OTLP endpoint configuration and authentication to the SDKs through environment variables. Restart your deployment to ensure the annotations and auto-instrumentations are applied.For languages where auto-instrumentation is not available, manually instrument your application. See the [Setup section in the corresponding SDK](https://docs-v3-preview.elastic.dev/elastic/opentelemetry/tree/main/reference/edot-sdks).
  </step>

  <step title="Install the content packs">
    Install the **[Kubernetes OpenTelemetry Assets](https://docs-v3-preview.elastic.dev/elastic/integration-docs/tree/main/reference/kubernetes_otel)** and **[System OpenTelemetry Assets](https://docs-v3-preview.elastic.dev/elastic/integration-docs/tree/main/reference/system_otel)** integrations in Kibana.
  </step>

  <step title="Explore your data">
    Go to Kibana and select **Dashboards** to explore your newly collected data.
  </step>
</stepper>


## Using the `elasticsearch` exporter

If you need to write telemetry directly to Elasticsearch — for example, for pipeline customizations not yet supported through Elastic Cloud Managed OTLP Endpoint — use the following configuration instead.
Create the secret with your Elasticsearch endpoint:
```bash
kubectl create namespace opentelemetry-operator-system
kubectl create secret generic elastic-secret-otel \
--namespace opentelemetry-operator-system \
--from-literal=elastic_endpoint='<ELASTICSEARCH_ENDPOINT>' \
--from-literal=elastic_api_key='<ELASTIC_API_KEY>'
```

Install the Operator using the standard values file:
```bash
helm install opentelemetry-kube-stack open-telemetry/opentelemetry-kube-stack \
--namespace opentelemetry-operator-system \
--values 'https://raw.githubusercontent.com/elastic/elastic-agent/refs/tags/v9.5.1/deploy/helm/edot-collector/kube-stack/values.yaml' \
--version '0.12.4'
```


## Troubleshooting

The following issues might occur.

### API key prefix not found

The following error is due to an improperly formatted API key:
```txt
Exporting failed. Dropping data.
{"kind": "exporter", "data_type": }
"Unauthenticated desc = ApiKey prefix not found"
```

Format your API key as `"Authorization": "ApiKey <api-key-value-here>"` or `"Authorization=ApiKey <api-key>"` depending on whether you're using a Collector or SDK.
For additional troubleshooting, refer to [Troubleshooting common issues with the Elastic Agent](https://docs-v3-preview.elastic.dev/elastic/docs-content/pull/7920/troubleshoot/ingest/opentelemetry/edot-collector) and [Troubleshooting the EDOT SDKs](https://docs-v3-preview.elastic.dev/elastic/docs-content/pull/7920/troubleshoot/ingest/opentelemetry/edot-sdks).