OpenTelemetry Collector on Kubernetes with Helm Chart – Part 3
Published: 2022-11-13 14:16:00

**Written by [Yoav Danieli](https://www.linkedin.com/in/yoav-danieli/) @ Team Aspecto**


In this article, you will learn how to use the OpenTelemetry Helm chart to deploy a collector as a gateway in a Kubernetes cluster.

In previous tutorials, I demonstrated how to deploy the OpenTelemetry Collector as both Gateway and Agent on a Kubernetes cluster. It took a lot of work and hours of research. Luckily there is an easier way. Enter Helm Charts.

#### Related Guides

-   [The OpenTelemetry Collector and how to configure it](https://www.aspecto.io/blog/opentelemetry-collector-guide?utm_source=dev.to&utm_medium=post&utm_campaign=opentelemetry-collector-on-kubernetes-helm-part-3/)
-   [Distributed tracing with OpenTelemetry Collector on Kubernetes -- Part 1](https://www.aspecto.io/blog/distributed-tracing-with-opentelemetry-collector-on-kubernetes/?utm_source=dev.to&utm_medium=post&utm_campaign=opentelemetry-collector-on-kubernetes-helm-part-3)
-   [OpenTelemetry Collector as an Agent on Kubernetes -- Part 2](https://www.aspecto.io/blog/opentelemetry-collector-agent-on-kubernetes/?utm_source=dev.to&utm_medium=post&utm_campaign=opentelemetry-collector-on-kubernetes-helm-part-3)

What is Helm?
-------------

Before we start using Helm, let's give it a quick introduction.

Helm is an [open-source package manager](https://helm.sh/) for Kubernetes. It allows software built for Kubernetes to be provided, used, and shared. It's also a graduate [project](https://www.cncf.io/announcements/2020/04/30/cloud-native-computing-foundation-announces-helm-graduation/) from the Cloud Native Computing Foundation (CNCF), similar to Kubernetes, Jaeger, and OpenTelemetry (although OTel is still incubating).

Helm packages software uses a format called Charts. A chart is a collection of files that form a set of Kubernetes resources. We can use a single chart to deploy simple things like a single-pod hello-world program or enormously complex stuff like a full-stack web app with HTTP servers, databases, caches, and more.

For more information about Helm, visit Helm [Docs](https://helm.sh/docs/).

Now let's dive right in and figure out how to use the Helm [chart](https://github.com/open-telemetry/opentelemetry-helm-charts) provided by OpenTelemetry.

Using OpenTelemetry Helm Chart
------------------------------

### Installing Opentelemetry-Collector Helm Chart

1\. Install Helm using homebrew.

```
brew install helm
```

Add the OpenTelemetry helm repository. A helm repository is an HTTP server from which we can find and install helm charts. The following command will establish a connection with the repository server and allow us to find and install its resources.

```
helm repo add open-telemetry https://open-telemetry.github.io/opentelemetry-helm-charts
```

3\. Search the repo and find out which charts it offers:

```
helm search repo open-telemetry
```

This will produce the following output:

```
NAME                                    CHART VERSION   APP VERSION     DESCRIPTION
open-telemetry/opentelemetry-collector  0.34.0          0.61.0          OpenTelemetry Collector Helm chart for Kubernetes
open-telemetry/opentelemetry-demo       0.3.1           0.4.0-alpha     opentelemetry demo helm chart
open-telemetry/opentelemetry-operator   0.13.0          0.60.0          OpenTelemetry Operator Helm chart for Kubernetes
```

The repository offers three charts:

-   **OpenTelemetry-collector** -- The chart that we will use to create the collector.

-   **OpenTelemetry-demo** -- This is a demo chart that creates an incredibly complex microservice system. It's written in many programming languages, and you can find good examples for almost any use case you need.

-   **OpenTelemetry-operator** -- This chart helps us set up an OpenTelemetry operator in our project. The operator provides the implementation of the OpenTelemetry collector and injects auto instrumentation to the services running inside our cluster. I will demonstrate the usage of the OpenTelemetry collector in future articles.

When using a helm chart, we are provided with a pre-defined set of parameters. These parameters, as well as their default values, can be found in a file called values.yml. To show the file, we can use the command:

```
helm show values open-telemetry/opentelemetry-collector
```

But it is easier to jump to the chart [source code](https://github.com/open-telemetry/opentelemetry-helm-charts/blob/main/charts/opentelemetry-collector/values.yaml) and look at the files in the browser. I will not elaborate on each of the values, instead, I will demonstrate how to create the same Gateway Collector deployment we created above. Hopefully, it would be much simpler.

First, clean up your cluster and remove all resources within it. Getting started with a clean slate

Let's install the chart as is. With its default values.

```
helm install opentelemetry-collector open-telemetry/opentelemetry-collector
```

We get an error. 

```
[ERROR] 'mode' must be set.
```

As stated in the source code from the link above. The default value for mode is set to an empty string while valid values are `'deployment'`. `'daemonset'` or `'statefulset'`.

Let's add a mode value. 

Create a collector-values.yml file and set the mode to deployment, the same as our Gateway.

```
helm install opentelemetry-collector open-telemetry/opentelemetry-collector -f ./collector-values.yml
```

So now we have an up-and-running collector. 

💡Pro Tip -- We can replace the command 'install' with 'template' to see the exact Kubernetes resources rendered and deployed to the cluster. Looking at the resources generated by the helm chart, we see similarities to the resources we used ourselves. And all we did was install the chart with a specific mode!

### OpenTelemetry-Collector Helm Chart Configuration

To configure it the same way as the Gateway collector we deployed in the previous chapters, there are more values we need to set. Let's start with the configuration taken from the chart's [examples](https://github.com/open-telemetry/opentelemetry-helm-charts/tree/main/charts/opentelemetry-collector/examples) under 'deployment-otlp-traces'.

```
mode: deployment

ports:
  jaeger-compact:
    enabled: false
  jaeger-thrift:
    enabled: false
  jaeger-grpc:
    enabled: false
  zipkin:
    enabled: false

config:
  receivers:
    jaeger: null
    prometheus: null
    zipkin: null
  service:
    pipelines:
      traces:
        receivers:
          - otlp
      metrics: null
      logs: null
```

Here we disable the ports we are not using and enable only the traces pipeline, with only the otlp receiver. This configuration will install a collector that receives telemetry data via grpc and http protocols in otlp format. 

There are no exporters defined, so the chart will render the default exporter which is a simple logging. Let's add the OTLP exporter for Aspecto, our distributed tracing platform. And let's also add Jaeger exporter:

```
config:
 receivers:
   jaeger: null
   prometheus: null
   zipkin: null
 exporters:
   otlp/aspecto:
     endpoint: otelcol.aspecto.io:4317
     headers:
       Authorization: ${ASPECTO_API_KEY}
   jaeger:
     endpoint: jaeger-all-in-one:14250
     tls:
       insecure: true
   logging:
     loglevel: debug
 service:
   telemetry:
     logs:
       level: debug
   pipelines:
     traces:
       receivers:
         - otlp
       exporters:
         - otlp/aspecto
         - jaeger
         - logging
     metrics: null
     logs: null

```

Populate the ASPECTO_API_KEY with a secret, same as above. The OpenTelemetry collector chart supports it by using the extraEnv property:

```
extraEnvs:
 - name: ASPECTO_API_KEY
   valueFrom:
     secretKeyRef:
       name: aspecto
       key: api-key
       optional: false
```

We also need to expose our collector to the internet using the load balancer service:

```
service:
 type: LoadBalancer
```

The last thing we should do is tell the helm chart which OpenTelemetry collector image it should use and how. By default, it uses the latest image from the otel/opentelemetry-collector-contrib docker repo. 

We want to change it to the stable collector-core image of our choosing tag.

```
image:
 repository: otel/opentelemetry-collector
 tag: "latest"

command:
 name: otelcol
```

Upgrade the deployment:

```
helm upgrade opentelemetry-collector open-telemetry/opentelemetry-collector -f ./collector-values.yml
```

And also deploy Jaeger UI, so we can visualize our traces:

```
kubectl apply -f jaeger.yml
```

After checking the logs and status of our Collector and Jaeger deployments and verifying everything is ready, we can start our test service to generate traces. 

Once the service runs, you should see traces reaching the destinations configured in the exporter's section.

Final Thoughts and Aspecto Helm Chart
-------------------------------------

Using the OpenTelemetry-Collector Helm chart was simple and quick compared to manually defining each resource. I highly recommend using it in your clusters. 

If you reach a point where you need to extend those resources or add properties that are not enabled via the helm chart, you can output the template resource with the helm template command and use it. Easy peasy.

In addition, some distributed tracing vendors offer their own helm chart to add a vendor-specific functionality to the Collector configuration. 

Check Aspecto Helm charts [here](https://github.com/aspecto-io/helm-charts/tree/master/charts/opentelemetry-collector).

[ASPECTO HELM CHART](https://github.com/aspecto-io/helm-charts/tree/master/charts/opentelemetry-collector)

Thanks for reading, and if you have any questions, I'm happy to [connect and help](https://www.linkedin.com/in/yoav-danieli/).

P.S. You can find a lot of the concepts covered here in our latest live workshop on deploying the OpenTelemetry Collector on Kubernetes.

{% embed https://youtu.be/X60owauFkGA %}