Skip to content

Install Jaeger Helmchart in Azure Kubernetes Services (AKS)

Introduction

Distributed tracing is a critical component in modern observability, especially when we're working with microservices architectures. Jaeger is one of the most popular open-source distributed tracing tools, and with Helm, it’s easy to deploy and manage on Kubernetes.

In this article, we will walk through how to install the Jaeger Helm Chart in Azure Kubernetes Service (AKS). Helm simplifies application deployment on Kubernetes, and combining it with Jaeger allows you to get valuable insights into your services' latency, dependencies, and performance metrics.

Objective

The objective of this article is to provide step-by-step instructions to install Jaeger on an Azure Kubernetes Service (AKS) cluster using Helm, access the Jaeger UI locally, expose it through Ingress, and use Jaeger for distributed tracing.

In this exercise we will accomplish & learn how to implement following:

  • Step 1: Login into Azure
  • Step 2. Connect to AKS Cluster
  • Step 3. Add the Jaeger Helm Chart Repository
  • Step 4. Install Jaeger with Helm
  • Step 5. Install Jaeger Helmchart using terraform
  • Step 6. Verify Jaeger Installation in AKS
  • Step 7. Access Jaeger Locally - port forwarding
  • Step 8. Configure Ingress for Jaeger UI
  • Step 9. Jaeger Integration with OpenTelemetry
  • Step 10. Uninstalling the Chart

Prerequisites

Before proceeding with the installation of Jaeger in AKS, ensure that you have the following prerequisites:

  • Azure CLI – Ensure that the Azure CLI is installed on your local machine. Install Azure CLI
  • kubectl – Kubernetes command-line tool installed. Install kubectl
  • Helm – Helm should be installed for managing Kubernetes applications. Install Helm
  • Azure Subscription – You need an Azure account and sufficient permissions to create AKS clusters.
  • Terraform (Optional) – If you choose to install Jaeger via Terraform, ensure Terraform is installed. Install Terraform
  • AKS Cluster – An existing AKS cluster should be available, or you can create one using the Azure CLI.

Step 1: Login into Azure

Ensure that you are logged into the correct Azure subscription before proceeding.

# Login to Azure
az login 

# Shows current Azure subscription
az account show

# Lists all available Azure subscriptions
az account list

# Sets Azure subscription to desired subscription using ID
az account set -s "anji.keesari"

Follow the on-screen instructions to complete the login process.

Step 2: Connect to AKS Cluster

Once logged in and set your subscription then connect to your AKS cluster. with your AKS cluster name:

Use the az aks get-credentials command to connect to the AKS cluster.

# Azure Kubernetes Service Cluster User Role
az aks get-credentials -g "rg-aks-dev" -n "aks-cluster1-dev"

# Azure Kubernetes Service Cluster Admin Role
az aks get-credentials -g "rg-aks-dev" -n "aks-cluster1-dev" --admin

# get nodes
kubectl get no
kubectl get namespace -A

Step 3: Add the Jaeger Helm Chart Repository

Jaeger’s Helm chart is hosted in the GitHub / Artifact. To begin, add the Jaeger Helm repository to your Helm setup:

List all added Helm repositories:

helm repo list

Add the Jaeger Helm repository:

helm repo add jaegertracing https://jaegertracing.github.io/helm-charts

Update the Helm repositories:

helm repo update jaegertracing

Step 4: Install Jaeger Helmchart

Now, you can install Jaeger using Helmchart. Execute the following command:

Let's first search the helm chart which we want to install. here I am installing official jaegertracing helmchart.

Search for available charts and versions in the Jaeger repository:

helm search repo jaegertracing

output

NAME                            CHART VERSION   APP VERSION     DESCRIPTION
jaegertracing/jaeger            3.4.1           1.53.0          A Jaeger Helm chart for Kubernetes       
jaegertracing/jaeger-operator   2.57.0          1.61.0          jaeger-operator Helm chart for Kubernetes

Let's first see the values:

helm show values jaegertracing/jaeger --version 3.4.1 > jaeger\values.yaml

Customize the values.yaml file for OpenTelemetry Integration later.

# before 
cassandra: false
# after
cassandra: true

# before 
allInOne:
  enabled: true

# after
allInOne:
  enabled: false

# before 
storage:  
  type: memory 
# after
storage:  
  type: cassandra

# before 
agent:
  enabled: true
# after
agent:
  enabled: false

# before 
collector:
  enabled: false

# after
collector:
  enabled: true

# before 
query:
  enabled: false
# after
query:
  enabled: true

Install : use this command if you need to create namespace along with helm install

helm install jaeger jaegertracing/jaeger -n jaeger --create-namespace --version 3.4.1 --values jaeger\values.yaml

Upgrade : use this command if you already have namespace created

helm upgrade --install jaeger jaegertracing/jaeger -n jaeger --version 3.4.1

Alt text

This command installs Jaeger in your AKS cluster. You can customize the installation by providing values files or using Helm chart options.

Step 5. Install Jaeger Helmchart using terraform

Declare Variables for Jaeger Installation

To begin with, we’ll define a few Terraform variables that will control whether Jaeger is enabled and specify the version of Jaeger we want to install.

# declare variables section
variable "jaeger_enabled" {
  description = "Use this variable to skip the Jaeger Helm install"
  type        = bool
  default     = true
}

variable "jaeger_version" {
  type    = string
  default = "3.4.0"
}
  • jaeger_enabled: This boolean variable allows you to control whether Jaeger should be installed. Set it to true to install Jaeger, or false to skip the installation.
  • jaeger_version: This specifies the version of the Jaeger Helm chart to install. In this example, we’re using version 3.4.0.

Create a Namespace for Jaeger Resources

Next, we need to create a dedicated namespace for Jaeger resources in the Kubernetes cluster. We'll ensure that the namespace is created only if Jaeger installation is enabled (jaeger_enabled is true).

# create a new namespace for Jaeger resources 
resource "kubernetes_namespace" "jaeger" {
  count = var.jaeger_enabled ? 1 : 0
  metadata {
    name = "jaeger"
  }
  depends_on = [
    azurerm_kubernetes_cluster.aks
  ]
}

This step ensures that all Jaeger-related resources are deployed in a dedicated jaeger namespace, which keeps the cluster organized. The depends_on ensures the Kubernetes cluster is available before the namespace creation.

Install Jaeger Using Helm Chart

Now, we will use the helm_release resource in Terraform to install the Jaeger Helm chart into the Kubernetes cluster.

# Install Jaeger Helm chart using Terraform
resource "helm_release" "jaeger" {
  count      = var.jaeger_enabled ? 1 : 0
  name       = "jaeger"
  repository = "https://jaegertracing.github.io/helm-charts"
  chart      = "jaeger"
  version    = var.jaeger_version
  namespace  = kubernetes_namespace.jaeger[0].metadata.0.name
  values = [
    "jaeger/values.yaml"
  ]
  depends_on = [
    azurerm_kubernetes_cluster.aks,
    kubernetes_namespace.jaeger
  ]
}
  • name: Defines the name of the Helm release, in this case, jaeger.
  • repository: Specifies the repository URL where the Jaeger Helm chart is hosted.
  • chart: The name of the chart you want to install, which is jaeger.
  • version: This is set to the version you declared earlier (3.4.0).
  • namespace: This specifies the jaeger namespace where the release will be installed.
  • values: The path to your values.yaml file, which can be customized as per your Jaeger configuration needs.
  • depends_on: Ensures that the Kubernetes cluster and namespace are created before deploying Jaeger.

Apply the Terraform Configuration

Once you’ve defined your Terraform configuration, you can run the following commands to apply the changes and install Jaeger in your Kubernetes cluster.

terraform init
terraform apply
  • terraform init: Initializes your Terraform configuration.
  • terraform apply: Applies the configuration, provisioning the Jaeger Helm chart on your Kubernetes cluster.

Step 6: Verify Jaeger Resources in AKS

To verify that Jaeger has been successfully installed, you can list the Kubernetes resources:

helm list --namespace jaeger
output

NAME    NAMESPACE       REVISION        UPDATED                                 STATUS          CHART           APP VERSION
jaeger  jaeger          1               2025-03-23 19:38:38.1348651 -0700 PDT   deployed        jaeger-3.4.1    1.53.0
kubectl get pods -n jaeger
# List all pods in the default namespace
kubectl get all -n jaeger
kubectl get configmap,secret,ingress,all -n jaeger

output

NAME                         DATA   AGE
configmap/kube-root-ca.crt   1      12m

NAME                                  TYPE                 DATA   AGE
secret/sh.helm.release.v1.jaeger.v1   helm.sh/release.v1   1      3m32s

NAME                         READY   STATUS    RESTARTS   AGE
pod/jaeger-bb7764c48-4bfbb   1/1     Running   0          3m31s

NAME                       TYPE        CLUSTER-IP   EXTERNAL-IP   PORT(S)                                                    AGE
service/jaeger-agent       ClusterIP   None         <none>        5775/UDP,5778/TCP,6831/UDP,6832/UDP                        3m32s
service/jaeger-collector   ClusterIP   None         <none>        9411/TCP,14250/TCP,14267/TCP,14268/TCP,4317/TCP,4318/TCP   3m32s
service/jaeger-query       ClusterIP   None         <none>        16686/TCP,16685/TCP                                        3m32s

NAME                     READY   UP-TO-DATE   AVAILABLE   AGE
deployment.apps/jaeger   1/1     1            1           3m32s

NAME                               DESIRED   CURRENT   READY   AGE
replicaset.apps/jaeger-bb7764c48   1         1         1       3m32s
You should see Jaeger pods and services running in your cluster.

Describe Jaeger pod for more details

kubectl describe pod/jaeger-bb7764c48-4bfbb -n jaeger

Describe Jaeger pod logs for more details

kubectl logs pod/jaeger-bb7764c48-4bfbb -n jaeger

Step 7: Access Jaeger Locally - port forwarding

To connect to your Jaeger server using a client, you need to create a port forward:

kubectl port-forward service/jaeger-query -n jaeger 16686:16686
or
kubectl port-forward service/jaeger-query -n jaeger 80:16686

To access the Jaeger web UI:

http://localhost:16686/search
# or
http://localhost:80

Now, you can access Jaeger by opening your web browser. Use the default username (admin) to log in.

After running the above commands, you should be able to access Jaeger in your web browser.

http://localhost:16686/search

Jaeger > Login page

Alt text

Step 8: Configure Ingress for Jaeger

If you want to access Jaeger externally, you can configure Ingress. First, create an Ingress resource:

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: jaeger-ingress
  namespace: jaeger
spec:
  rules:
  - host: jaeger.example.com  # Replace with your domain
    http:
      paths:
      - path: /
        pathType: Prefix
        backend:
          service:
            name: jaeger-query
            port:
              number: 16686

Apply the Ingress configuration:

kubectl apply -f jaeger-ingress.yaml

Step 9: Jaeger Integration with OpenTelemetry

When integrating Jaeger with OpenTelemetry (OTEL) and deploying it on Azure Kubernetes Service (AKS), there are some specific adjustments you'll need to make to your setup. The OpenTelemetry Operator and OpenTelemetry Collector play key roles in this integration, and the configuration of Jaeger needs to be aligned with the OpenTelemetry ecosystem. Here’s an updated version of the values.yaml and the overall architecture, with the changes aligned to the OpenTelemetry Operator and OpenTelemetry Collector integration:

  • OpenTelemetry Operator manages OpenTelemetry resources like the OpenTelemetry Collector, which is a vendor-agnostic component that can receive, process, and export telemetry data from your applications. The OpenTelemetry Operator helps deploy and manage the OpenTelemetry Collector and other OpenTelemetry components in Kubernetes.

  • OpenTelemetry Collector will receive trace data from your microservices and forward it to Jaeger for storage and visualization. The OpenTelemetry Collector will act as the intermediary between your applications and Jaeger. The collector receives telemetry data from OpenTelemetry-instrumented services (using the OpenTelemetry SDK or auto-instrumentation) and forwards that data to Jaeger.

  • Jaeger will act as the trace storage backend, which stores and visualizes trace data collected by the OpenTelemetry Collector. In this setup:

Customization of values.yaml Aligned with OpenTelemetry Integration

Given that we're using OpenTelemetry along with Jaeger, the values.yaml customizations should reflect the fact that OpenTelemetry will handle the tracing and then forward it to Jaeger. Here’s the corrected and aligned configuration:

1. Enable Cassandra as Storage for Jaeger

You still need to configure Jaeger to use Cassandra as a storage backend if you're aiming for production-level scale.

# before 
cassandra: false
# after 
cassandra: true

Explanation: You're enabling Cassandra as the persistent backend for Jaeger, which will handle the storage of the trace data collected via OpenTelemetry.

2. Disable All-in-One Jaeger Mode

Since you're using OpenTelemetry for collection and Jaeger for storage/visualization, the modular mode is more appropriate than the all-in-one configuration.

# before 
allInOne:
  enabled: true

# after 
allInOne:
  enabled: false

Explanation: Disabling the all-in-one setup means that Jaeger's components (collector, query, etc.) will be deployed separately. This gives you more control and scalability, especially when dealing with microservices.

3. Change Jaeger’s Storage Backend to Cassandra

You are integrating Jaeger with OpenTelemetry, and you need to make sure that Jaeger’s storage backend is properly set to Cassandra to handle the large volumes of trace data.

# before 
storage:  
  type: memory 
# after 
storage:  
  type: cassandra

Explanation: The memory backend was the default for testing, but for production workloads, Cassandra is a more reliable and scalable solution.

4. Disable Jaeger Agent

Since the OpenTelemetry Collector will be receiving traces and forwarding them to Jaeger, the Jaeger agent is no longer needed. The OpenTelemetry Collector will handle the trace collection.

# before 
agent:
  enabled: true

# after
agent:
  enabled: false

Explanation: Disabling the Jaeger agent ensures that the OpenTelemetry Collector is the sole component responsible for collecting and forwarding trace data to Jaeger.

5. Enable Jaeger Collector

Now that you’re disabling the Jaeger agent, you need to ensure that the Jaeger collector is enabled, as the OpenTelemetry Collector will forward the trace data to it.

# before 
collector:
  enabled: false

# after
collector:
  enabled: true

Explanation: The Jaeger collector is required to collect and store the trace data forwarded from the OpenTelemetry Collector. * It’s important to have this component enabled to handle the data collection, processing, and export to the backend.

6. Enable Jaeger Query UI

The Jaeger query UI is essential for visualizing trace data, and it should be enabled so that your team can access the data.

# before 
query:
  enabled: false

# after
query:
  enabled: true

Explanation: Enabling the query UI allows you to access and explore the traces in Jaeger, providing insights into your microservices' performance.

Step 10: Uninstalling the Chart

Once you're done experimenting, you can delete the Jaeger deployment and associated resources from AMK:

To uninstall/delete the jaeger helm deployment run:

helm list --namespace jaeger
helm delete jaeger -n jaeger
kubectl delete namespace jaeger
The command removes all the Kubernetes components associated with the chart and deletes the release.

Uninstall helm chart

helm uninstall jaeger -n jaeger

Conclusion

In this guide, we have walked through the process of installing Jaeger in an Azure Kubernetes Service (AKS) cluster using Helm. We covered verifying the installation, accessing the Jaeger UI locally and through Ingress, and using Jaeger for distributed tracing in your applications.

Jaeger is a powerful tool for gaining observability into your microservices architecture, and deploying it in AKS can help you monitor and troubleshoot your applications effectively.

Reference