Author : HASSAN MD TAREQ | Updated : 2021/05/15

What Is Helm?

Helm = Package Manager + Template Engine + Other

Links

What Is Helm Chart?

Structure of an Helm chart

myapp/              # Helm chart (defines how to deploy your application)
  -Chart.yaml        # chart definition (e.g. name, version)
  -requirements.yaml # OPTIONAL: dependencies (other charts) that will be deployed together with your chart
  -values.yaml       # values for the template variables
  -templates/        # directory containing the template files (Kubernetes manifests)

Chart.yaml

name: my-app
version: v0.0.1
description: A Kubernetes-Native Application

values.yaml

replicas: 3
containers:
- name: container-1
  image: my-registry.tld/my-image:tag
  env:
  - name: MY_ENV
    value: "some env var value"
  resources:
    limits:
      cpu: "200m"
      memory: "300Mi"

templates/deployment.yaml


# deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: my-deployment
spec:
  replicas: {{ .Values.replicas | default 1 }}
  selector: ...
  template:
    metadata: ...
    spec:
      containers:
        {{- range $containerIndex, $container := Values.containers }}
        - name: {{ $container.name | default "container" | quote }}
          image: {{ $container.image | quote }}
          env:
{{ toYaml $container.env | indent 12 }}
          {{- if $container.resources }}
          resources:
            {{- with $container.resources.limits }}
            limits:
              cpu: {{ .cpu | quote }}
              memory: {{ .memory | quote }}
            {{- end }}
          {{- end }}
        {{- end }}

requirements.yaml

dependencies:
- name: mysql
  version: 3.2.1

Azure Container Registry For Helm Charts

To enable OCI support for Helm (required to push Helm charts to ACR), HELM_EXPERIMENTAL_OCI environment variable needs to be set ‘1’.

Open cmd or PowerShell as Administrator and execute following commands

# check helm version (must be v3+)
helm version

# 
# Permanently set an environment variable
# For current user only: setx VAR_NAME "VALUE"
# For all users: setx /M VAR_NAME "VALUE"
#
setx HELM_EXPERIMENTAL_OCI 1     # For current user only
setx /M HELM_EXPERIMENTAL_OCI 1  # For all users

# For current session of cmd or PowerShell (avoid, instead permanently set 'HELM_EXPERIMENTAL_OCI' environment variable)
$env:HELM_EXPERIMENTAL_OCI=1  # PowerShell
set HELM_EXPERIMENTAL_OCI=1   # cmd

Check HELM_EXPERIMENTAL_OCI is set

$env:HELM_EXPERIMENTAL_OCI     # PowerShell
echo %HELM_EXPERIMENTAL_OCI%   # cmd

Creating Helm Chart

Save chart to local registry cache

#
# check 'HELM_EXPERIMENTAL_OCI` environment variable is set
#
$env:HELM_EXPERIMENTAL_OCI

#
# save chart
#
helm chart save . demoapp:v1

#
# create an alias with the fully qualified name of the registry (all lowercase) and the target repository and tag
# it will be pushed to Azure Container Registry
# 
helm chart save . myacr.azurecr.io/helm/demoapp:v1

Check helm chart is saved to local registry cache

helm chart list

Pushing Helm Chart To Azure Container Registry

Commands

#
# Authenticate with the registry
# echo $spPassword | helm registry login myacr.azurecr.io --username myacr --password-stdin
#
echo <myacr-user-password> | helm registry login myacr.azurecr.io --username myacr --password-stdin

#
# Check chart alias (`myacr.azurecr.io/helm/demoapp:v1`) exists in local cache
#
helm chart list

#
# Push to ACR
#
helm chart push myacr.azurecr.io/helm/demoapp:v1

Check chart was pushed to ACR

Pulling Helm Charts From ACR

#
# Delete local cache if needed
#
helm chart remove myacr.azurecr.io/helm/demoapp:v1
helm chart list # checking that chart was removed

#
# Pulling helm chart from ACR
#
helm chart pull myacr.azurecr.io/helm/demoapp:v1
helm chart list # checking that chart was pulled

Using ACR Helm Charts To Deploy Applications to AKS

Use Visual Studio developer PowerShell (right click on the chart folder > opne in terminal) or open Cmder PowerShell as Admin and execute following commands

#
# Check 'HELM_EXPERIMENTAL_OCI' is set
# Setting command: $env:HELM_EXPERIMENTAL_OCI=1
# 
$env:HELM_EXPERIMENTAL_OCI     # PowerShell


#
# Authenticate with the registry
# echo $spPassword | helm registry login myacr.azurecr.io --username myacr --password-stdin
#
echo <myacr-user-password> | helm registry login myacr.azurecr.io --username myacr --password-stdin


#
# Check repositories in ACR
#
az acr repository list --name myacr --output tsv
az acr repository show --name myacr --repository helm/demoapp --output tsv

#
# Check target *Helm Chart) repository
#
az acr repository show-tags --name myacr --repository helm/demoapp
az acr repository show-manifests --name myacr --repository helm/demoapp
az acr repository show-manifests --name myacr --repository helm/demoapp --detail


#
# Check helm charts in local cahe
# 
helm chart list


#
# Delete local cache if needed
#
helm chart remove myacr.azurecr.io/helm/demoapp:v1
helm chart list # checking that chart was removed

#
# Pulling helm chart from ACR
#
helm chart pull myacr.azurecr.io/helm/demoapp:v1

#
# Exporting (expanding) helm chart to a folder so that chart can be deployed to AKS by using helm command
#
$AcrHelmChartName = "demoapp"
$AcrHelmChartsExportFolder = "C:\acr_helm_charts"
$ExportedHelmChartPath = "$AcrHelmChartsExportFolder\$AcrHelmChartName"

helm chart export myacr.azurecr.io/helm/demoapp:v1 --destination $AcrHelmChartsExportFolder


#
# AKS credentials
#
az aks get-credentials --resource-group xyz-rg --name xyz-aks-cluster

#
# Make sure using correct AKS namespace
#
kubectl config view --minify | grep namespace 
kubectl create namespace demo  # Create namespace if needed
kubectl config set-context --current --namespace demo  # switch to target namespace
kubectl config view --minify | grep namespace  # verify namespace is switched correctly

#
# Install helm chart to target AKS namespace
# helm install [NAME] [CHART] [flags]
# helm install --namespace demo <release-name> $ExportedHelmChartPath
# use --namespace even though we switched to target namespace (extra careful)
# 
helm install --namespace demo demoapp-release $ExportedHelmChartPath

#
# Check release
#
helm list --namespace demo