Installing Alauda Distributed Tracing with OpenSearch
Installing the Alauda Distributed Tracing platform involves the following steps:
- Installing the Alauda Build of OpenTelemetry v2 Operator
- Deploying the Alauda Build of Jaeger v2
- Deploying the OpenTelemetry Collector to forward traces to Jaeger
TOC
Installing the Alauda Build of OpenTelemetry v2 OperatorInstalling via the web consoleInstalling via the CLIDeploying the Alauda Build of Jaeger v2Deploying the OpenTelemetry CollectorVerification(Optional) Enabling Service Performance Monitoring (SPM)UninstallingInstalling the Alauda Build of OpenTelemetry v2 Operator
The Alauda Build of OpenTelemetry v2 Operator manages the lifecycle of Jaeger v2 and OpenTelemetry Collector instances. You must install this Operator before deploying any tracing components.
Installing via the web console
Follow the instructions in the Installing via the web console section of the Alauda Build of OpenTelemetry v2 documentation.
Installing via the CLI
Follow the instructions in the Installing via the CLI section of the Alauda Build of OpenTelemetry v2 documentation.
Deploying the Alauda Build of Jaeger v2
Jaeger v2 is deployed as an OpenTelemetryCollector custom resource managed by the Alauda Build of OpenTelemetry v2 Operator. It uses a backend storage and integrates with the Alauda Container Platform authentication system through an OAuth2 Proxy sidecar.
Prerequisites
- The Alauda Build of OpenTelemetry v2 Operator is installed.
- An OpenSearch 3.x instance is available, and you have the endpoint URL, username, and password for it.
- An active ACP CLI (
kubectl) session by a cluster administrator with thecluster-adminrole. - The
jqcommand-line tool is installed.
Procedure
-
Set user-configurable environment variables for connecting to OpenSearch:
Replace the placeholder values with your actual OpenSearch credentials.
-
Retrieve platform configuration and Jaeger-related container images from the cluster:
NOTEVerify that commands completes without errors.
-
Set default environment variables. You can adjust these values to match your deployment requirements:
-
Create the Jaeger namespace and OpenSearch credentials Secret:
Verify that the Secret was created:
-
Create a Secret for the OAuth2 Proxy, which is used to integrate the Jaeger UI with the Alauda Container Platform authentication:
-
Create a file named
jaeger.yamlwith the following content:- The
prometheus: kube-prometheuslabel is inherited by the auto-createdServiceMonitorresource, enabling ACP Prometheus to scrape Jaeger metrics. - The Jaeger v2 container image. This is not the default OpenTelemetry Collector image; it is a custom Jaeger binary built on the OpenTelemetry Collector framework.
- Resource requests and limits for the Jaeger container. Adjust based on your expected trace volume; higher throughput environments may require more CPU and memory.
- Enables the Prometheus metrics endpoint for the Jaeger instance.
- The
jaeger_storageextension configures the OpenSearch backend for storing trace data. - The
opensearchdriver selects the OpenSearch storage implementation. Jaeger uses the same implementation for OpenSearch as for Elasticsearch. service_cache_ttlcontrols how long the service name cache is kept. The default is12h. If the index retention is short, reduce this value to ensure the Jaeger UI can discover services promptly.max_span_ageis the maximum age of spans the query service will search, set here fromJAEGER_MAX_SPAN_AGE. Keep it aligned with thejaeger-es-index-cleanerretention so the UI does not query indices that have already been deleted.index_prefixmust match theINDEX_PREFIXused by thejaeger-es-index-cleanerCronJob, otherwise the cleaner cannot find the indices to delete. For more details on shards and replicas tuning, see Shards and Replicas.rollover_frequency: daytogether withdate_layoutproduces daily indices such as${JAEGER_ES_INDEX_PREFIX}-jaeger-span-YYYY-MM-DD. These plain daily indices (no rollover alias) are what thejaeger-es-index-cleanermatches by date suffix.- The
jaeger_queryextension serves the Jaeger Query API and the Jaeger UI. - The
additionalContainerssection defines the OAuth2 Proxy sidecar, which handles authentication for the Jaeger UI by integrating with the Alauda Container Platform Dex identity provider. - Resource requests and limits for the OAuth2 Proxy sidecar. This container has low resource requirements since it only proxies authentication requests.
- The
-
Render the manifest with
envsubstand apply the configuration: -
Wait for the Jaeger Pod to be ready:
-
Deploy the
jaeger-es-index-cleanerto periodically remove expired indices.Why notjaeger-es-rollover init? Theinitsubcommand of thejaeger-es-rollovertool calls the Elasticsearch_ilm/policy/...endpoint to verify that an ILM policy exists, but OpenSearch uses_plugins/_ism/policies/...instead. The two are not compatible, soinitfails on OpenSearch (see jaegertracing/jaeger#7121).This guide uses daily indices plus
jaeger-es-index-cleaner, which does not rely on rollover aliases and therefore does not requirejaeger-es-rollover init.How it works
The OpenSearch backend writes daily indices such as
acp-<cluster>-jaeger-span-2026-04-22. Thejaeger-es-index-cleanermatches indices named<prefix>-jaeger-(span|service|dependencies|sampling)-YYYY-MM-DD, compares the date suffix with "today minus N days", and deletes the indices that are older than the retention period.Set the index-cleaner environment variables:
INFORelationship between the retention parameter and Jaeger
To prevent the Jaeger UI from querying indices that the cleaner has just deleted, keep
JAEGER_INDEX_RETENTION_DAYS(the cleaner retention) consistent with Jaeger'smax_span_age(JAEGER_MAX_SPAN_AGE). For example, set both to 7 days (168h). -
Create
jaeger-index-cleaner.yamlto deploy the index-cleaner as aCronJob:scheduleuses a standard Cron expression (UTC). Schedule it during off-peak hours; once per day is usually sufficient.concurrencyPolicy: Forbidensures a new Job is not started while the previous cleanup is still running, avoiding concurrent deletions that could briefly stress OpenSearch.argsare the positional arguments ofjaeger-es-index-cleaner: the first is the retention in days, the second is the OpenSearch endpoint.ROLLOVER=trueis intentionally not set, so the default daily-index matching mode is used.INDEX_PREFIXmust exactly match the Jaegerindices.index_prefix(hereacp-<cluster>), otherwise the cleaner cannot find the corresponding indices.ES_TLS_SKIP_HOST_VERIFY=truecorresponds to the Jaeger-sideinsecure_skip_verify: trueTLS policy. If you instead harden TLS with a self-signed CA, mount the CA into the container and setES_TLS_CA_FILEto its path.
Render and deploy the CronJob:
-
Label the namespace and create an Ingress to expose the Jaeger UI:
Wait for the Ingress to be ready:
Verification
Access the Jaeger UI at <platform-url>/clusters/<cluster-name>/jaeger, where <platform-url> is the Alauda Container Platform URL and <cluster-name> is the name of your cluster.
Run the following command to print the Jaeger UI URL:
Deploying the OpenTelemetry Collector
After Jaeger v2 is running, deploy an OpenTelemetry Collector instance to receive trace data from instrumented applications and forward it to Jaeger.
-
Create a file named
otel-collector.yamlwith the following content:- The
prometheus: kube-prometheuslabel enables ACP Prometheus to scrape the Collector metrics via the auto-createdServiceMonitor. - Resource requests and limits for the Collector container. Adjust based on your expected trace throughput.
- Enables the Operator to automatically create
ServiceMonitorresources for the Collector's metrics endpoint. - The OTLP receiver accepts trace data over gRPC (port
4317) and HTTP (port4318) from instrumented applications. - The
otlp/tracesexporter forwards received traces to the Jaeger collector service. The endpoint is derived from the Jaeger instance name and namespace. - The trace pipeline receives data via OTLP and Zipkin, processes it through
memory_limiterandbatch, and exports to both thedebugexporter (for logging) andotlp/traces(for forwarding to Jaeger).
- The
-
Render the manifest with
envsubstand apply the configuration: -
Wait for the Collector pod to be ready:
Verification
After installing all components, verify the end-to-end tracing pipeline by generating sample trace data.
-
Deploy
telemetrygenas a test client to generate sample traces:NOTEThe
--otlp-endpointmust point to the OpenTelemetry Collector service deployed in the previous step. -
Open the Jaeger UI at
<platform-url>/clusters/<cluster-name>/jaeger.Select the
telemetrygenservice from the Service dropdown and click Find Traces to verify that the generated traces are visible.Run the following command to print the Jaeger UI URL:
(Optional) Enabling Service Performance Monitoring (SPM)
Service Performance Monitoring (SPM) surfaces in the Jaeger UI as the Monitor tab, aggregating span data to produce RED (Request, Error, Duration) metrics. This enables you to identify performance issues without requiring prior knowledge of service or operation names. For more details, see Service Performance Monitoring (SPM).
Enabling SPM requires running the SpanMetrics Connector inside Jaeger to generate the RED metrics, and routing spans from the front OpenTelemetry Collector to Jaeger through a loadbalancing exporter so the metrics stay accurate even when both components run with multiple replicas. Jaeger exposes the metrics on a Prometheus endpoint and serves them back to the Monitor tab through a PromQL-compatible backend.
Prerequisites
- Jaeger v2 and the OpenTelemetry Collector are deployed (all previous steps completed).
- ACP monitoring is available in the cluster.
Procedure
-
Retrieve monitoring endpoint and credentials from the cluster:
-
Create a Secret for monitoring credentials:
-
Patch the OpenTelemetry Collector to forward spans to Jaeger through a
loadbalancingexporter instead of the directotlp/tracesexporter. Withrouting_key: service, all spans of a given service are consistently sent to the same Jaeger replica, so the SpanMetrics Connector running inside Jaeger (next step) aggregates each service exactly once. This is what keeps the metrics correct when the Collector or Jaeger runs with more than one replica:The
dnsresolver discovers every Jaeger collector Pod through the headless Service that the OpenTelemetry Operator provisions automatically (${JAEGER_INSTANCE_NAME}-collector-headless), so no additional Service or RBAC is required.Wait for the Collector to restart:
-
Create a file named
jaeger-spm-patch.yamlwith the following content. This patch runs the SpanMetrics Connector inside Jaeger, exposes the generated RED metrics on a Prometheus endpoint, and adds a PromQL metrics backend so Jaeger can serve them to the Monitor tab:- The
monitoring-credentialsvolume mounts the monitoring basic-auth credentials into the Jaeger container. - The
monitoring-credentialsvolumeMount makes the credentials available at/etc/jaeger/monitoring-credentials/. - The
spanmetricsconnector generates RED metrics from the spans Jaeger receives. Because the Collector routes each service to a single Jaeger replica, every replica aggregates a disjoint set of services correctly. - The
prometheusexporter exposes the generated metrics on port8889. The Jaeger instance already carries theprometheus: kube-prometheuslabel andobservability.metrics.enableMetrics: true(set injaeger.yaml), so the Operator automatically creates aServiceMonitorthat lets ACP Prometheus scrape this endpoint. - The
basicauth/monitoringextension provides basic authentication for the monitoring metrics endpoint. - The
metric_backendssection configures the PromQL-compatible metrics storage that Jaeger queries for SPM data. - Reference the metrics store in the
jaeger_queryextension. - The
basicauth/monitoringextension must be added to theservice.extensionslist to be active. - The
tracespipeline now also exports tospanmetrics(storage plus metrics generation), and a dedicatedmetrics/spanmetricspipeline forwards the generated metrics to theprometheusexporter.
WARNINGThe
volumes,volumeMounts,service.extensions, and pipelineexportersfields are arrays. A merge patch replaces arrays entirely rather than appending to them. The patch file above includes all existing entries alongside the new ones to prevent data loss. - The
-
Apply the patch:
Wait for Jaeger to restart:
To run SPM in high availability, increase spec.replicas on the otel and ${JAEGER_INSTANCE_NAME} collectors; no other change is required. The stateless Collector tier scales freely, and because spans are load-balanced by service, each Jaeger replica owns a disjoint set of services and aggregates them without conflict. Keep these caveats in mind:
Verification
After enabling SPM, you can verify it by deploying the telemetrygen test client as described in the Verification section above.
Once traces are generated, navigate to the Monitor tab in the Jaeger UI to view the aggregated RED metrics for the telemetrygen service.
Uninstalling
To remove the Alauda Distributed Tracing components from your cluster, follow Uninstalling Alauda Distributed Tracing.