Chapter 1. Configuring distributed tracing


The Tempo Operator uses a custom resource definition (CRD) file that defines the architecture and configuration settings for creating and deploying distributed tracing resources. You can install the default configuration or modify the file.

1.1. Configuring the Tempo Operator

You can configure the Tempo Operator by using the Operator Lifecycle Manager (OLM) Subscription custom resource (CR) to override default settings. This configuration method uses environment variables that take precedence over any ConfigMap-based configuration.

The following Subscription CR example shows Operator configuration:

apiVersion: operators.coreos.com/v1alpha1
kind: Subscription
metadata:
  name: tempo-product
  namespace: openshift-tempo-operator
spec:
  channel: stable
  name: tempo-product
  source: redhat-operators
  sourceNamespace: openshift-marketplace
  config:
    env:
    - name: FEATURE_GATES
      value: "openshift.route,openshift.servingCertsService"
    - name: TLS_PROFILE
      value: "Modern"

where:

FEATURE_GATES
Specifies a comma-separated list of feature gates to enable or disable. Prefix a gate with - to disable it.
TLS_PROFILE
Specifies the TLS security profile for the Operator.
Tip

You can also configure these values from the OpenShift Container Platform web console by editing the Subscription object under Operators > Installed Operators > Tempo Operator > Subscription.

You can configure the Tempo Operator by using the environment variables from the following tables.

The following table shows the feature gates:

Expand
Feature gateDescription

openshift.route

Enables OpenShift Container Platform route creation for Tempo components.

openshift.servingCertsService

Enables OpenShift Container Platform service serving certificates.

openshift.oauthProxy

Enables OpenShift Container Platform OAuth proxy integration.

httpEncryption

Enables HTTP encryption for Tempo components.

grpcEncryption

Enables gRPC encryption for Tempo components.

prometheusOperator

Enables Prometheus Operator integration for metrics.

grafanaOperator

Enables Grafana Operator integration.

builtInCertManagement

Enables built-in certificate management.

observability.metrics.createServiceMonitors

Enables creation of ServiceMonitor resources for Prometheus.

observability.metrics.createPrometheusRules

Enables creation of PrometheusRule resources for alerts.

networkPolicies

Enables creation of NetworkPolicy resources.

The following table shows the general configuration environment variables:

Expand
Environment variableDescriptionExample value

FEATURE_GATES

Lists comma-separated feature gates to enable or disable. Prefix a gate with - to disable it.

openshift.route,openshift.servingCertsService,-networkPolicies

TLS_PROFILE

Sets TLS security profile type.

Old, Intermediate, or Modern

OPENSHIFT_BASE_DOMAIN

Sets the OpenShift Container Platform base domain for route generation.

apps.example.com

DEFAULT_POD_SECURITY_CONTEXT

Sets the default PodSecurityContext object as JSON.

{"runAsNonRoot": true}

The following table shows the built-in certificate management environment variables:

Expand
Environment variableDescriptionExample value

BUILT_IN_CERT_MANAGEMENT_CA_VALIDITY

CA certificate validity duration.

8760h

BUILT_IN_CERT_MANAGEMENT_CA_REFRESH

CA certificate refresh interval.

7008h

BUILT_IN_CERT_MANAGEMENT_CERT_VALIDITY

Certificate validity duration.

2160h

BUILT_IN_CERT_MANAGEMENT_CERT_REFRESH

Certificate refresh interval.

1728h

The following table shows the controller manager environment variables:

Expand
Environment variableDescriptionExample value

METRICS_BIND_ADDRESS

Metrics server bind address.

:8080

METRICS_SECURE

Enables secure metrics serving.

true

HEALTH_PROBE_BIND_ADDRESS

Health probe bind address.

:8081

WEBHOOK_PORT

Webhook server port.

9443

1.2. Configuring back-end storage

For information about configuring the back-end storage, see Understanding persistent storage and the configuration section for your chosen storage option.

The TempoStack custom resource (CR) defines the architecture and settings for creating distributed tracing resources. You can modify these parameters to customize your implementation to your business needs.

The following TempoStack CR is an example:

apiVersion: tempo.grafana.com/v1alpha1
kind: TempoStack
metadata:
  name: <name>
spec:
  storage: {}
  resources: {}
  replicationFactor: 1
  retention:
    global:
      traces: 48h
    perTenant: {}
  template:
      distributor: {}
      ingester: {}
      compactor: {}
      querier: {}
      queryFrontend: {}
      gateway: {}
  limits:
    global:
      ingestion: {}
      query: {}
  observability:
    grafana: {}
    metrics: {}
    tracing: {}
  search: {}
  managementState: managed

where:

apiVersion
API version to use when creating the object.
kind
The kind of Kubernetes object to create.
metadata
Data that uniquely identifies the object, including a name string, UID, and optional namespace. OpenShift Container Platform automatically generates the UID and completes the namespace with the name of the project where the object is created.
name
Name of the TempoStack instance.
spec
Configuration parameters of the TempoStack instance. When a common definition for all Tempo components is required, define it in the spec section. When the definition relates to an individual component, place it in the spec.template.<component> section.
storage
Storage is configured at instance deployment. See the installation page for information about storage options for the instance.
resources
Compute resources for the Tempo container.
replicationFactor
Integer value for the number of ingesters that must acknowledge the data from the distributors before accepting a span.
retention
Configuration options for retention of traces. The default value is 48h.
distributor
Configuration options for the Tempo distributor component.
ingester
Configuration options for the Tempo ingester component.
compactor
Configuration options for the Tempo compactor component.
querier
Configuration options for the Tempo querier component.
queryFrontend
Configuration options for the Tempo query-frontend component.
gateway
Configuration options for the Tempo gateway component.
limits
Limits for ingestion and query rates.
ingestion
Ingestion rate limits.
query
Query rate limits.
observability
Configuration of Operands to handle telemetry data.
search
Search capabilities.
managementState
Whether or not this CR is managed by the Operator. The default value is managed.
Expand
Table 1.1. TempoStack CR parameters
ParameterDescriptionValuesDefault value

apiVersion:

API version to use when creating the object.

tempo.grafana.com/v1alpha1

tempo.grafana.com/v1alpha1

kind:

Defines the kind of Kubernetes object to create.

tempo

 

metadata:

Data that uniquely identifies the object, including a name string, UID, and optional namespace.

 

OpenShift Container Platform automatically generates the UID and completes the namespace with the name of the project where the object is created.

name:

Name for the object.

Name of your TempoStack instance.

tempo-all-in-one-inmemory

spec:

Specification for the object to be created.

Contains all of the configuration parameters for your TempoStack instance. When a common definition for all Tempo components is required, it is defined under the spec node. When the definition relates to an individual component, it is placed under the spec.template.<component> node.

N/A

resources:

Resources assigned to the TempoStack instance.

  

storageSize:

Storage size for ingester PVCs.

  

replicationFactor:

Configuration for the replication factor.

  

retention:

Configuration options for retention of traces.

  

storage:

Configuration options that define the storage.

  

template.distributor:

Configuration options for the Tempo distributor.

  

template.ingester:

Configuration options for the Tempo ingester.

  

template.compactor:

Configuration options for the Tempo compactor.

  

template.querier:

Configuration options for the Tempo querier.

  

template.queryFrontend:

Configuration options for the Tempo query frontend.

  

template.gateway:

Configuration options for the Tempo gateway.

  

1.4. TempoStack deployment sizing

Deployment size configuration uses the spec.size field in the TempoStack custom resource (CR) as follows.

apiVersion: tempo.grafana.com/v1alpha1
kind: TempoStack
metadata:
  name: example
  namespace: tracing-system
spec:
  size: 1x.pico
  storageSize: 1Gi
  storage:
    secret:
      name: object-storage-secret
      type: s3
  template:
    queryFrontend:
      jaegerQuery:
        enabled: true

where:

size
Specifies the deployment size. Valid values are 1x.demo, 1x.pico, 1x.extra-small, 1x.small, and 1x.medium. Do not change the number 1x for the deployment size.

The TempoStack instance size format is 1x.<size>, where 1x is the only supported value and <size> specifies the performance tier, as the following table shows:

Expand
 1x.demo1x.pico1x.extra-small1x.small1x.medium

Ingestion rate

Demo use only

Small workloads

100 GB/day

500 GB/day

2 TB/day

Replication factor

1

2

2

2

2

Total CPU requests

None

3.25 vCPUs

4.6 vCPUs

7.9 vCPUs

24 vCPUs

Total CPU requests if using the gateway

None

3.4 vCPUs

5.1 vCPUs

8.8 vCPUs

28.1 vCPUs

Total CPU requests if using the Jaeger UI

None

3.4 vCPUs

5.1 vCPUs

8.8 vCPUs

28.1 vCPUs

Total memory requests

None

8.8 Gi

22.1 Gi

30.1 Gi

47.1 Gi

Total memory requests if using the gateway

None

8.9 Gi

22.3 Gi

30.4 Gi

47.4 Gi

Total memory requests if using the Jaeger UI

None

8.9 Gi

22.3 Gi

30.4 Gi

47.4 Gi

For production deployments, use 1x.pico or larger sizes that provide high availability with a replication factor of 2.

Note

The 1x.demo size is for demonstration and development purposes only. It has no resource constraints and a replication factor of 1, so it does not provide high availability.

The Operator automatically configures the resource requests for all TempoStack components and sets the appropriate replication factor. You do not need to manually configure individual component resources. The base resource totals include the following components: distributor, ingester, compactor, querier, and query front end. The gateway component is optional but required if you need multitenant authentication. When enabled, it also deploys the gateway Open Policy Agent (OPA) sidecar. The Jaeger UI component is optional and provides the Jaeger query interface for trace visualization. When enabled, it also deploys the OAuth proxy for authentication.

The following table shows the CPU and memory resource requests for each TempoStack component at each deployment size:

Expand
Component1x.pico1x.extra-small1x.small1x.medium
 

CPU

Memory

CPU

Memory

CPU

Memory

CPU

Memory

Distributor

500m

500 Mi

200m

128 Mi

600m

128 Mi

1500m

128 Mi

Ingester

500m

3 Gi

1500m

8 Gi

2000m

10 Gi

8000m

16 Gi

Compactor

500m

500 Mi

200m

4 Gi

400m

6 Gi

600m

10 Gi

Querier

750m

1536 Mi

1000m

1 Gi

2500m

3 Gi

5000m

4 Gi

Query front end

500m

500 Mi

200m

1 Gi

400m

1 Gi

800m

1 Gi

Gateway

100m

64 Mi

400m

128 Mi

800m

192 Mi

4000m

192 Mi

Gateway OPA

50m

64 Mi

100m

64 Mi

100m

64 Mi

200m

128 Mi

Jaeger UI

100m

64 Mi

400m

128 Mi

800m

192 Mi

4000m

192 Mi

OAuth proxy

50m

64 Mi

100m

64 Mi

100m

64 Mi

200m

128 Mi

Note
  • The resource values listed are requests only. The Operator does not apply resource limits.
  • The replication factor determines the number of ingester replicas. For sizes with a replication factor of 2, multiply the ingester resources by 2 to calculate the total ingester resource consumption.
  • The Operator automatically deploys the gateway OPA sidecar when the gateway is enabled.
  • The Operator automatically deploys the OAuth proxy when the Jaeger UI is enabled.

When determining resources for a component, the Operator uses the following priority order:

  1. Component override: If you set spec.template.<component>.resources, the Operator uses these values.
  2. Size profile: If you set spec.size, the Operator uses the t-shirt size profile values.
  3. Total resources: If you set spec.resources.total, the Operator uses the percentage-based split.
  4. No resources: If you do not set any of the previous options, the Operator does not apply resource requests.

Component-level overrides always take precedence. You can do any of the following actions:

  • Customize specific components when using a t-shirt size as the baseline for the remaining components.
  • Override resource requests for specific components when using a t-shirt size as the baseline.
  • Override resource requests when a particular component in your deployment requires more or fewer resources than the default size profile provides.

The following example shows a TempoStack custom resource with component resource overrides:

apiVersion: tempo.grafana.com/v1alpha1
kind: TempoStack
metadata:
  name: example
  namespace: tracing-system
spec:
  size: 1x.small
  storageSize: 1Gi
  storage:
    secret:
      name: object-storage-secret
      type: s3
  template:
    ingester:
      resources:
        requests:
          cpu: 4
          memory: 20Gi
    querier:
      replicas: 4
    queryFrontend:
      jaegerQuery:
        enabled: true

where:

example
In this example, the following settings apply: The ingester component uses the explicitly defined resources, 4 CPU and 20 Gi memory, instead of the 1x.small defaults. The querier component uses four replicas with resources from the 1x.small profile. All the other components, such as the distributor, compactor, and query front end, use the 1x.small default resources.
size
Specifies the base size profile for all components.
resources
Overrides the ingester resources. The ingester component uses these explicit values instead of the 1x.small defaults.
replicas
Specifies the number of querier replicas. The replica counts are independent of the size profile.

1.5. Query configuration options

Two components of distributed tracing, the querier and query frontend, manage queries. You can configure both of these components.

The querier component finds the requested trace ID in the ingesters or back-end storage. Depending on the set parameters, the querier component can query both the ingesters and pull bloom or indexes from the back end to search blocks in object storage. The querier component exposes an HTTP endpoint at GET /querier/api/traces/<trace_id>, but it is not expected to be used directly. Queries must be sent to the query frontend.

The following table shows the configuration parameters for the querier component:

Expand
ParameterDescriptionValues

nodeSelector

The simple form of the node-selection constraint.

type: object

replicas

The number of replicas to be created for the component.

type: integer; format: int32

tolerations

Component-specific pod tolerations.

type: array

The query frontend component is responsible for sharding the search space for an incoming query. The query frontend exposes traces via a simple HTTP endpoint: GET /api/traces/<trace_id>. Internally, the query frontend component splits the blockID space into a configurable number of shards and then queues these requests. The querier component connects to the query frontend component via a streaming gRPC connection to process these sharded queries.

The following table shows the configuration parameters for the query frontend component:

Expand
ParameterDescriptionValues

component

Configuration of the query frontend component.

type: object

component.nodeSelector

The simple form of the node selection constraint.

type: object

component.replicas

The number of replicas to be created for the query frontend component.

type: integer; format: int32

component.tolerations

Pod tolerations specific to the query frontend component.

type: array

jaegerQuery

The options specific to the Jaeger Query component.

type: object

jaegerQuery.enabled

When enabled, creates the Jaeger Query component,jaegerQuery.

type: boolean

jaegerQuery.ingress

The options for the Jaeger Query ingress.

type: object

jaegerQuery.ingress.annotations

The annotations of the ingress object.

type: object

jaegerQuery.ingress.host

The hostname of the ingress object.

type: string

jaegerQuery.ingress.ingressClassName

The name of an IngressClass cluster resource. Defines which ingress controller serves this ingress resource.

type: string

jaegerQuery.ingress.route

The options for the OpenShift route.

type: object

jaegerQuery.ingress.route.termination

The termination type. The default is edge.

type: string (enum: insecure, edge, passthrough, reencrypt)

jaegerQuery.ingress.type

The type of ingress for the Jaeger Query UI. The supported types are ingress, route, and none.

type: string (enum: ingress, route)

jaegerQuery.monitorTab

The monitor tab configuration.

type: object

jaegerQuery.monitorTab.enabled

Enables the monitor tab in the Jaeger console. The PrometheusEndpoint must be configured.

type: boolean

jaegerQuery.monitorTab.prometheusEndpoint

The endpoint to the Prometheus instance that contains the span rate, error, and duration (RED) metrics. For example, https://thanos-querier.openshift-monitoring.svc.cluster.local:9092.

type: string

The following TempoStack CR example shows configuration of the query frontend component:

apiVersion: tempo.grafana.com/v1alpha1
kind: TempoStack
metadata:
  name: simplest
spec:
  storage:
    secret:
      name: minio
      type: s3
  storageSize: 200M
  resources:
    total:
      limits:
        memory: 2Gi
        cpu: 2000m
  template:
    queryFrontend:
      jaegerQuery:
        enabled: true
        ingress:
          route:
            termination: edge
          type: route

1.6. Configuring the UI plugin

You can use the distributed tracing UI plugin of the Cluster Observability Operator (COO) as the user interface (UI) for distributed tracing. For more information about installing and using the distributed tracing UI plugin, see "Distributed tracing UI plugin" in Cluster Observability Operator.

1.7. Grafana data source integration

When you enable the gateway, it uses the OpenShift Container Platform authentication and authorization mechanisms. As a result, you can query different tenants. The gateway prevents the data source from communicating directly with the distributed tracing back end and requires authentication through the gateway.

Tip

Due to architectural constraints or operational limitations, you might not be able to directly integrate Grafana with OpenShift Container Platform authentication, such as when using an external Grafana instance. In this case, you can use a ServiceAccount token configured with an extended lifespan for gateway authentication. All users who are authenticated this way share the same access privileges. This shared access model limits the granularity of access control, preventing the implementation of highly detailed, user-specific permissions. If your organization requires robust, fine-grained access management, this approach is less suitable.

1.8. Configuring the Monitor tab in Jaeger UI

You can have the request rate, error, and duration (RED) metrics extracted from traces and visualized through the Jaeger Console in the Monitor tab of the OpenShift Container Platform web console.

Prerequisites

  • You have configured the permissions and tenants for distributed tracing. For more information, see "Configuring the permissions and tenants".
Note

Prometheus that you deploy in your user-workload monitoring stack scrapes metrics from spans in the OpenTelemetry Collector. The Jaeger UI queries these metrics from the Prometheus endpoint and visualizes them.

Procedure

  1. In the OpenTelemetryCollector custom resource of the OpenTelemetry Collector, enable the Span Metrics Connector, which derives metrics from traces and exports the metrics in the Prometheus format.

    The following OpenTelemetryCollector custom resource example configures span RED:

    apiVersion: opentelemetry.io/v1beta1
    kind: OpenTelemetryCollector
    metadata:
      name: otel
    spec:
      mode: deployment
      observability:
        metrics:
          enableMetrics: true
      config: |
        connectors:
          spanmetrics:
            metrics_flush_interval: 15s
    
        receivers:
          otlp:
            protocols:
              grpc:
              http:
    
        exporters:
          prometheus:
            endpoint: 0.0.0.0:8889
            add_metric_suffixes: false
            resource_to_telemetry_conversion:
              enabled: true
    
          otlp/traces:
            auth:
              authenticator: bearertokenauth
            endpoint: tempo-redmetrics-gateway.mynamespace.svc.cluster.local:8090
            headers:
              X-Scope-OrgID: dev
            tls:
              ca_file: /var/run/secrets/kubernetes.io/serviceaccount/service-ca.crt
              insecure: false
    
        extensions:
          bearertokenauth:
            filename: /var/run/secrets/kubernetes.io/serviceaccount/token
    
        service:
          extensions:
          - bearertokenauth
          pipelines:
            traces:
              receivers: [otlp]
              exporters: [otlp/traces, spanmetrics]
            metrics:
              receivers: [spanmetrics]
              exporters: [prometheus]
    
    # ...

    where:

    enableMetrics
    Creates the ServiceMonitor custom resource to enable scraping of the Prometheus exporter.
    spanmetrics
    The Span Metrics Connector receives traces and exports metrics.
    otlp
    The OTLP receiver receives spans in the OpenTelemetry protocol.
    prometheus
    The Prometheus Exporter exports metrics in the Prometheus format.
    enabled
    Resource attributes are dropped by default.
    exporters
    The Span Metrics Connector is configured as an exporter in the traces pipeline.
    receivers
    The Span Metrics Connector is configured as a receiver in the metrics pipeline.
  2. In the TempoStack custom resource, enable the Monitor tab and set the Prometheus endpoint to the Thanos querier service to query the data from your user-defined monitoring stack.

    The following TempoStack custom resource example enables the Monitor tab:

    apiVersion: tempo.grafana.com/v1alpha1
    kind: TempoStack
    metadata:
      name: redmetrics
    spec:
      storage:
        secret:
          name: minio-test
          type: s3
      storageSize: 1Gi
      tenants:
        mode: openshift
        authentication:
          - tenantName: dev
            tenantId: "1610b0c3-c509-4592-a256-a1871353dbfa"
      template:
        gateway:
          enabled: true
        queryFrontend:
          jaegerQuery:
            monitorTab:
              enabled: true
              prometheusEndpoint: https://thanos-querier.openshift-monitoring.svc.cluster.local:9092
              redMetricsNamespace: ""
    
    # ...

    where:

    enabled
    Enables the monitoring tab in the Jaeger console.
    prometheusEndpoint
    Service name for Thanos Querier from user-workload monitoring.
  3. Optional: Use the span RED metrics that the Span Metrics Connector generates with alerting rules.

    For example, for alerts about a slow service or to define service level objectives (SLOs), the connector creates a traces_span_metrics_duration_bucket histogram and the traces_span_metrics_calls counter metric. The following example PrometheusRule custom resource defines an alerting rule for SLO when not serving 95% of requests within 2000 ms on the front-end service:

    apiVersion: monitoring.coreos.com/v1
    kind: PrometheusRule
    metadata:
      name: span-red
    spec:
      groups:
      - name: server-side-latency
        rules:
        - alert: SpanREDFrontendAPIRequestLatency
          expr: histogram_quantile(0.95, sum(rate(traces_span_metrics_duration_bucket{service_name="frontend", span_kind="SPAN_KIND_SERVER"}[5m])) by (le, service_name, span_name)) > 2000
          labels:
            severity: Warning
          annotations:
            summary: "High request latency on {{$labels.service_name}} and {{$labels.span_name}}"
            description: "{{$labels.instance}} has 95th request latency above 2s (current value: {{$value}}s)"

    where:

    expr
    Expression for checking if 95% of the front-end server response time values are below 2000 ms. The time range ([5m]) must be at least four times the scrape interval and long enough to accommodate a change in the metric.

1.9. Configuring the receiver TLS

The custom resource of a TempoStack or TempoMonolithic instance supports configuring the TLS for receivers by using user-provided certificates or OpenShift’s service-serving certificates.

You can provide a TLS certificate in a secret or use the service serving certificates that are generated by OpenShift Container Platform.

  • To provide a TLS certificate in a secret, configure it in the TempoStack custom resource.

    Note

    This feature is not supported with the enabled Tempo Gateway.

    The following example shows TLS for receivers by using a user-provided certificate in a secret:

    apiVersion: tempo.grafana.com/v1alpha1
    kind:  TempoStack
    # ...
    spec:
    # ...
      template:
        distributor:
          tls:
            enabled: true
            certName: <tls_secret>
            caName: <ca_name>
    # ...

    where:

    enabled
    Enables TLS at the Tempo Distributor.
    certName
    Secret containing a tls.key key and tls.crt certificate that you apply in advance.
    caName
    Optional CA in a config map to enable mutual TLS authentication (mTLS).
  • Alternatively, you can use the service serving certificates that are generated by OpenShift Container Platform.

    Note

    Mutual TLS authentication (mTLS) is not supported with this feature.

    The following example shows TLS for receivers by using the service serving certificates that are generated by OpenShift Container Platform:

    apiVersion: tempo.grafana.com/v1alpha1
    kind:  TempoStack
    # ...
    spec:
    # ...
      template:
        distributor:
          tls:
            enabled: true
    # ...

    where:

    enabled
    Sufficient TLS configuration at the Tempo Distributor.

You can provide a TLS certificate in a secret or use the service serving certificates that are generated by OpenShift Container Platform.

  • To provide a TLS certificate in a secret, configure it in the TempoMonolithic custom resource.

    Note

    This feature is not supported with the enabled Tempo Gateway.

    The following example shows TLS for receivers by using a user-provided certificate in a secret:

    apiVersion: tempo.grafana.com/v1alpha1
    kind:  TempoMonolithic
    # ...
      spec:
    # ...
      ingestion:
        otlp:
          grpc:
            tls:
              enabled: true
              certName: <tls_secret>
              caName: <ca_name>
    # ...

    where:

    enabled
    Enables TLS at the Tempo Distributor.
    certName
    Secret containing a tls.key key and tls.crt certificate that you apply in advance.
    caName
    Optional CA in a config map to enable mutual TLS authentication (mTLS).
  • Alternatively, you can use the service serving certificates that are generated by OpenShift Container Platform.

    Note

    Mutual TLS authentication (mTLS) is not supported with this feature.

    The following example shows TLS for receivers by using the service serving certificates that are generated by OpenShift Container Platform:

    apiVersion: tempo.grafana.com/v1alpha1
    kind:  TempoMonolithic
    # ...
      spec:
    # ...
      ingestion:
        otlp:
          grpc:
            tls:
              enabled: true
          http:
            tls:
              enabled: true
    # ...

    where:

    enabled
    Minimal configuration for TLS at the Tempo Distributor.

1.10. Configuring query RBAC

As an administrator, you can set up the query role-based access control (RBAC) to filter the span attributes for your users by the namespaces for which you granted them permissions.

Note

When you enable the query RBAC, users can still access traces from all namespaces, and the service.name and k8s.namespace.name attributes are also visible to all users.

Prerequisites

  • You are logged in to the cluster as a user with the cluster-admin role.

    Tip

    Ensure that your OpenShift CLI (oc) version is up to date and matches your OpenShift Container Platform version.

    You can verify your login by running the following command:

    $ oc whoami

Procedure

  1. Enable multitenancy and query RBAC in the TempoStack custom resource (CR), for example:

    apiVersion: tempo.grafana.com/v1alpha1
    kind: TempoStack
    metadata:
      name: simplest
      namespace: chainsaw-multitenancy
    spec:
      storage:
        secret:
          name: minio
          type: s3
      storageSize: 1Gi
      resources:
        total:
          limits:
            memory: 2Gi
            cpu: 2000m
      tenants:
        mode: openshift
        authentication:
          - tenantName: dev
            tenantId: "1610b0c3-c509-4592-a256-a1871353dbfb"
      template:
        gateway:
          enabled: true
          rbac:
            enabled: true
        queryFrontend:
          jaegerQuery:
            enabled: false

    where:

    gateway.enabled
    Always set to true.
    rbac.enabled
    Always set to true.
    jaegerQuery.enabled
    Always set to false.
  2. Create a cluster role and cluster role binding to grant the target users the permissions to access the tenant that you specified in the TempoStack CR, for example:

    apiVersion: rbac.authorization.k8s.io/v1
    kind: ClusterRole
    metadata:
      name: tempo-dev-read
    rules:
    - apiGroups: [tempo.grafana.com]
      resources: [dev]
      resourceNames: [traces]
      verbs: [get]
    ---
    apiVersion: rbac.authorization.k8s.io/v1
    kind: ClusterRoleBinding
    metadata:
      name: tempo-dev-read
    roleRef:
      apiGroup: rbac.authorization.k8s.io
      kind: ClusterRole
      name: tempo-dev-read
    subjects:
      - kind: Group
        apiGroup: rbac.authorization.k8s.io
        name: system:authenticated

    where:

    resources
    Tenant name in the TempoStack CR.
    name
    All authenticated OpenShift users.
  3. Grant the target users the permissions to read attributes for the project. You can do this by running the following command:

    $ oc adm policy add-role-to-user view <username> -n <project>

1.11. Using taints and tolerations

To schedule TempoStack pods on dedicated nodes, see How to deploy the different TempoStack components on infra nodes by using nodeSelector and tolerations in OpenShift 4.

1.12. Configuring monitoring and alerts

The Tempo Operator supports monitoring and alerts about each TempoStack component such as the distributor or ingester, and exposes upgrade and operational metrics about the Operator itself.

You can enable metrics and alerts of TempoStack instances.

Prerequisites

  • Monitoring for user-defined projects is enabled in the cluster.

Procedure

  1. To enable metrics of a TempoStack instance, set the spec.observability.metrics.createServiceMonitors field to true:

    apiVersion: tempo.grafana.com/v1alpha1
    kind: TempoStack
    metadata:
      name: <name>
    spec:
      observability:
        metrics:
          createServiceMonitors: true
  2. To enable alerts for a TempoStack instance, set the spec.observability.metrics.createPrometheusRules field to true:

    apiVersion: tempo.grafana.com/v1alpha1
    kind: TempoStack
    metadata:
      name: <name>
    spec:
      observability:
        metrics:
          createPrometheusRules: true

Verification

You can use the Administrator view of the web console to verify successful configuration:

  1. Go to Observe Targets, filter for Source: User, and check that ServiceMonitors in the format tempo-<instance_name>-<component> have the Up status.
  2. To verify that alerts are set up correctly, go to Observe Alerting Alerting rules, filter for Source: User, and check that the Alert rules for the TempoStack instance components are available.

When installing the Tempo Operator from the web console, you can select the Enable Operator recommended cluster monitoring on this Namespace checkbox, which enables the creation of metrics and alerts for the Tempo Operator.

If the checkbox was not selected during installation, you can manually enable metrics and alerts even after installing the Tempo Operator.

Procedure

  • Add the openshift.io/cluster-monitoring: "true" label in the project where the Tempo Operator is installed, which is openshift-tempo-operator by default.

Verification

You can use the Administrator view of the web console to verify successful configuration:

  1. Go to Observe Targets, filter for Source: Platform, and search for tempo-operator, which must have the Up status.
  2. To verify that alerts are set up correctly, go to Observe Alerting Alerting rules, filter for Source: Platform, and locate the Alert rules for the Tempo Operator.
Red Hat logoGithubredditYoutubeTwitter

Learn

Try, buy, & sell

Communities

About Red Hat

We deliver hardened solutions that make it easier for enterprises to work across platforms and environments, from the core datacenter to the network edge.

Making open source more inclusive

Red Hat is committed to replacing problematic language in our code, documentation, and web properties. For more details, see the Red Hat Blog.

About Red Hat Documentation

Legal Notice

Theme

© 2026 Red Hat
Back to top