Friday, 16 May 2025

How to use Helm charts

Case study: we want to install Elasticsearch via Helm chart. 

From  Elastic Stack Helm chart | Elastic Docs we can see that Elastic offers a repository of Helm charts: https://helm.elastic.co

Inspecting the local Helm repositories


Before adding some repo to our local system, we can check if that repo has already been added:

% helm repo list

NAME    URL
stable  https://charts.helm.sh/stable
bitnami https://charts.bitnami.com/bitnami

Each entry includes:
  • NAME: The local alias you’ve given to the repo.
  • URL: The actual remote chart repository URL.

Adding a new Helm repository


We first need to add Elastic Helm repository to our local Helm repository list:

% helm repo add elastic https://helm.elastic.co

We can choose an arbitrary local name for the repository we're adding. We used elastic as repository is provided by Elastic.


The next step is to update information of available charts locally from all added chart repositories, or from the one we've just added:

% helm repo update elastic                                              
Hang tight while we grab the latest from your chart repositories...
...Successfully got an update from the "elastic" chart repository
Update Complete. ⎈Happy Helming!⎈

helm repo update basically downloads all Helm charts from a given repo to our local registry.


To update repo index (fetch latest chart versions) for all local repositories:

% helm repo update


Inspecting charts in a local Helm repository


Let's now list all charts in elastic repository:

% helm search repo elastic
NAME                          CHART VERSION APP VERSION DESCRIPTION                                       
elastic/eck-elasticsearch    0.15.0                    Elasticsearch managed by the ECK operator         
elastic/elastic-agent        9.0.1        9.0.1      Elastic-Agent Helm Chart                          
elastic/elasticsearch        8.5.1        8.5.1      Official Elastic helm chart for Elasticsearch     
elastic/apm-attacher          1.1.3                    A Helm chart installing the Elastic APM Kuberne...
elastic/apm-server            8.5.1        8.5.1      Official Elastic helm chart for Elastic APM Server
elastic/eck-agent            0.15.0                    Elastic Agent managed by the ECK operator         
elastic/eck-apm-server        0.15.0                    Elastic APM Server managed by the ECK operator    
elastic/eck-beats            0.15.0                    Elastic Beats managed by the ECK operator         
elastic/eck-enterprise-search 0.15.0                    Elastic Enterprise Search managed by the ECK op...
elastic/eck-fleet-server      0.15.0                    Elastic Fleet Server as an Agent managed by the...
elastic/eck-kibana            0.15.0                    Kibana managed by the ECK operator                
elastic/eck-logstash          0.15.0                    Logstash managed by the ECK operator              
elastic/eck-operator          3.0.0        3.0.0      Elastic Cloud on Kubernetes (ECK) operator        
elastic/eck-operator-crds    3.0.0        3.0.0      ECK operator Custom Resource Definitions          
elastic/eck-stack            0.15.0                    Elastic Stack managed by the ECK Operator         
elastic/filebeat              8.5.1        8.5.1      Official Elastic helm chart for Filebeat          
elastic/kibana                8.5.1        8.5.1      Official Elastic helm chart for Kibana            
elastic/kube-state-metrics    5.30.1        2.15.0      Install kube-state-metrics to generate and expo...
elastic/logstash              8.5.1        8.5.1      Official Elastic helm chart for Logstash          
elastic/metricbeat            8.5.1        8.5.1      Official Elastic helm chart for Metricbeat        
elastic/pf-host-agent        8.14.3        8.14.3      Hyperscaler software efficiency. For everybody.   
elastic/profiling-agent      9.0.0        9.0.0      Hyperscaler software efficiency. For everybody.   
elastic/profiling-collector  9.0.0        9.0.0      Universal Profiling. Hyperscaler software effic...
elastic/profiling-symbolizer 9.0.0        9.0.0      Universal Profiling. Hyperscaler software effic...



Another way of checking all charts is to download index.yaml file from the remote repository. It contains information of ALL versions of ALL charts in the repo:


% curl https://helm.elastic.co/index.yaml
...
  - apiVersion: v2
    appVersion: 8.15.0
    created: "2024-08-08T09:05:09.582088545Z"
    description: 'Universal Profiling. Hyperscaler software efficiency. For everybody. '
    digest: 9f6a78ed179cda2792259ad7c73db32c2753bf5e3317135fca52fbfb48a8063c
    icon: https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt6ec3007768940247/63337a1f4d11fa0cfdb55244/illustration-deployment-3-arrows.png
    kubeVersion: '>= 1.22.0-0'
    name: profiling-symbolizer
    urls:
    - https://helm.elastic.co/helm/profiling-symbolizer/profiling-symbolizer-8.15.0.tgz
    version: 8.15.0
  - apiVersion: v2
    appVersion: 8.14.3
    created: "2024-07-11T13:35:06.289007371Z"
    description: 'Universal Profiling. Hyperscaler software efficiency. For everybody. '
    digest: 9d1656e80f9c96c3cf7fa2d0692c7318e34e20ff6ad1da13a6b4dae1c82bc990
    icon: https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt6ec3007768940247/63337a1f4d11fa0cfdb55244/illustration-deployment-3-arrows.png
    kubeVersion: '>= 1.22.0-0'
    name: profiling-symbolizer
    urls:
    - https://helm.elastic.co/helm/profiling-symbolizer/profiling-symbolizer-8.14.3.tgz
    version: 8.14.3
...

To see only versions of some particular chart e.g. eck-elasticsearch:

% curl -s https://helm.elastic.co/index.yaml | grep eck-elasticsearch
  eck-elasticsearch:
    name: eck-elasticsearch
    - https://helm.elastic.co/helm/eck-elasticsearch/eck-elasticsearch-0.15.0.tgz
    name: eck-elasticsearch
    - https://helm.elastic.co/helm/eck-elasticsearch/eck-elasticsearch-0.14.1.tgz
    name: eck-elasticsearch
    - https://helm.elastic.co/helm/eck-elasticsearch/eck-elasticsearch-0.14.0.tgz
    name: eck-elasticsearch
    - https://helm.elastic.co/helm/eck-elasticsearch/eck-elasticsearch-0.13.0.tgz
    name: eck-elasticsearch
    - https://helm.elastic.co/helm/eck-elasticsearch/eck-elasticsearch-0.12.1.tgz
    name: eck-elasticsearch
    - https://helm.elastic.co/helm/eck-elasticsearch/eck-elasticsearch-0.12.0.tgz
    name: eck-elasticsearch
    - https://helm.elastic.co/helm/eck-elasticsearch/eck-elasticsearch-0.11.0.tgz
    name: eck-elasticsearch
    - https://helm.elastic.co/helm/eck-elasticsearch/eck-elasticsearch-0.10.0.tgz
    name: eck-elasticsearch
    - https://helm.elastic.co/helm/eck-elasticsearch/eck-elasticsearch-0.9.1.tgz
    name: eck-elasticsearch
    - https://helm.elastic.co/helm/eck-elasticsearch/eck-elasticsearch-0.9.0.tgz
    name: eck-elasticsearch
    - https://helm.elastic.co/helm/eck-elasticsearch/eck-elasticsearch-0.8.0.tgz
    name: eck-elasticsearch
    - https://helm.elastic.co/helm/eck-elasticsearch/eck-elasticsearch-0.7.0.tgz
    name: eck-elasticsearch
    - https://helm.elastic.co/helm/eck-elasticsearch/eck-elasticsearch-0.7.0-SNAPSHOT.tgz
    name: eck-elasticsearch
    - https://helm.elastic.co/helm/eck-elasticsearch/eck-elasticsearch-0.6.0.tgz
    name: eck-elasticsearch
    - https://helm.elastic.co/helm/eck-elasticsearch/eck-elasticsearch-0.4.0.tgz
    name: eck-elasticsearch
    - https://helm.elastic.co/helm/eck-elasticsearch/eck-elasticsearch-0.3.0.tgz
    name: eck-elasticsearch
    - https://helm.elastic.co/helm/eck-elasticsearch/eck-elasticsearch-0.2.0.tgz
    name: eck-elasticsearch
    - https://helm.elastic.co/helm/eck-elasticsearch/eck-elasticsearch-0.1.1.tgz
    name: eck-elasticsearch
    - https://helm.elastic.co/helm/eck-elasticsearch/eck-elasticsearch-0.1.0.tgz
    - condition: eck-elasticsearch.enabled
      name: eck-elasticsearch
    - condition: eck-elasticsearch.enabled
      name: eck-elasticsearch
    ...

As the response is YAML document, we can use yq tool to extract exactly what we need:

% curl -s https://helm.elastic.co/index.yaml | yq '.entries | to_entries | .[].value[] | select(.name == "eck-elasticsearch") | "Name: " + .name + "\nVersion: " + .version + "\n\n"'

Name: eck-elasticsearch
Version: 0.15.0


Name: eck-elasticsearch
Version: 0.14.1


Name: eck-elasticsearch
Version: 0.14.0


Name: eck-elasticsearch
Version: 0.13.0


Name: eck-elasticsearch
Version: 0.12.1

...


Let's say we want to install elastic/eck-elasticsearch chart. How can we find its default values?

% helm show values elastic/eck-elasticsearch 
---
# Default values for eck-elasticsearch.
# This is a YAML-formatted file.

# Overridable names of the Elasticsearch resource.
# By default, this is the Release name set for the chart,
# followed by 'eck-elasticsearch'.
#
# nameOverride will override the name of the Chart with the name set here,
# so nameOverride: quickstart, would convert to '{{ Release.name }}-quickstart'
#
# nameOverride: "quickstart"
#
# fullnameOverride will override both the release name, and the chart name,
# and will name the Elasticsearch resource exactly as specified.
#
# fullnameOverride: "quickstart"

# Version of Elasticsearch.
#
version: 9.0.0

# Elasticsearch Docker image to deploy
#
# image:

# Labels that will be applied to Elasticsearch.
#
labels: {}

# Annotations that will be applied to Elasticsearch.
#
annotations: {}

# Settings for configuring Elasticsearch users and roles.
# ref: https://www.elastic.co/guide/en/cloud-on-k8s/current/k8s-users-and-roles.html
#
auth: {}

# Settings for configuring stack monitoring.
# ref: https://www.elastic.co/guide/en/cloud-on-k8s/current/k8s-stack-monitoring.html
#
monitoring: {}
  # metrics:
  #   elasticsearchRefs:
  #   - name: monitoring
  #     namespace: observability
  # logs:
  #   elasticsearchRefs:
  #   - name: monitoring
  #     namespace: observability
...
...
 
We can save this document into a local yaml file which we can then modify and adjust to our needs:

% helm show values elastic/eck-elasticsearch > eck-elasticsearch-values.yaml


How to find which resources will Helm chart deploy?


We have few options:

1) Dry-run install the chart and inspect output


% helm install my-fleet-server elastic/eck-fleet-server --dry-run --debug

This will render the templates using default values (or our custom --values file) and print all the generated Kubernetes YAML to stdout.

We need to look for Look for: Deployment, Service, Secret, ConfigMap, Pod or any custom resources (Agent, etc.).

2) Download the chart locally and inspect the templates


% helm pull elastic/eck-fleet-server --untar
% cd eck-fleet-server

Now we can inspect the files under templates/ and values.yaml.

We'll see:
  • All the resource templates (deployment.yaml, service.yaml, etc.)
  • Which fields can be customized.

3) Search the Helm chart source code on GitHub

We can inspect:
  • templates/ folder – actual YAML templates
  • values.yaml – configurable inputs
  • Chart.yaml – metadata


Installing Helm chart


To deploy Helm chart into the Kubernetes cluster by using our own values:

% helm install \
   my-elasticsearch \
   elastic/eck-elasticsearch \
   -f eck-elasticsearch-values.yaml \
   -n elastic-system \
   --create-namespace

We chose to deploy it in a custom namespace which we named elastic-system.


By default, helm install installs the chart into the Kubernetes cluster our kubectl is currently configured to use. Helm relies on the kubeconfig file (typically located at ~/.kube/config) to know which cluster to interact with.

helm install:
  • Reads the kubeconfig file used by kubectl.
  • Connects to the current Kubernetes context (cluster and namespace).
  • Installs the Helm chart to that cluster, unless you override the context or namespace.


We can control the target cluster and namespace using the following:

helm install my-release elastic/eck-elasticsearch --kube-context=my-cluster-context


To list contexts:

kubectl config get-contexts


To switch context:

kubectl config use-context my-cluster-context


Before we attempt to target a remote Kubernetes cluster, we need to ensure that:
  • Our ~/.kube/config contains valid credentials and cluster info.
  • We can interact with it using kubectl (test with kubectl get nodes or kubectl get pods).


To remove the repo from the local system:

% helm repo remove elastic

---

No comments: