Een (handige) Helm op een Kubernetes applicatie zetten

Handige helm

Gino Verwijs, 8 oktober 2021.


Deze blog is de deliverable voor het onderzoek naar de tool Helm voor Kubernetes. Ik onderzoek wat *Helm* is, waarom en hoe het te gebruiken is.

Gedurende deze minor heb ik geleerd om applicaties eenvoudiger te kunnen deployen naar de cloud. Het containerizen van een applicatie was hierin de eerste stap met behulp van Docker. De vervolgstap van meerdere containers te runnen was het toepassen van Kubernetes. Kubernetes vangt een hoop problemen voor ons op zoals het automatisch opnieuw opstarten van pods (lees: applicaties) wanneer deze down gaan, het verdelen van de workload over de nodes/pods en het onderling samenwerken/communiceren van containers binnen de Kubernetes cluster. Kubernetes doet dit met behulp van gemaakte .yaml bestanden.

Ik ga tijdens dit onderzoek kijken naar geschreven documentie over Helm om te begrijpen hoe Helm werkt en hoe ik het kan toepassen. Daarnaast ga ik een prototype maken die Helm en Kubernetes gebruikt. Om tot een conclusie te kunnen komen op de volgende hoofdvraag:

"Hoe kan het opzetten van een Helm het deployen van een applicatie op k8s eenvoudiger maken?"

Beantwoord ik de volgende deelvragen:

1. Wat is Helm?
2. Wat zijn de voordelen van Helm?
3. Wat zijn de nadelen van Helm?
4. Hoe passen we Helm toe?
5. Zijn er alternatieven voor Helm?

Ik gebruik hierbij de onderzoeksmethoden van ictresearchmethods. De gekozen methoden zijn literature study, prototyping en community research om Helm vanuit verschillende perspectieven te onderzoeken (HBO-i, z.d.).

Introductie Helm

Helm is een package manager voor Kubernetes zoals apt voor Unix systemen is of pip voor Python (Bagani, 2021). Helm maakt het dus mogelijk om software te installeren en up te graden, of het installeren van dependencies van software. Daarnaast maakt Helm het makkelijker om software te kunnen deployen door configuratie opties aan te bieden voor de software.

Helm is begonnen als een Deis project in 2015 en is in de loop der jaren gepromoveerd tot een graduation Cloud Native Computing Foundating (CNCF) project. CNCF maakt, onderzoekt en beheert technologieën en noemt deze projecten. Deze projecten zijn beschikbaar op GitHub en hebben verschillende fasen: Sandbox, incubating en graduation. Hierover is meer te lezen op de website van CNCF.

Helm packages maken gebruik van charts. Deze charts bestaan meestal uit .yaml configuratiebestanden en templates voor Kubernetes manifest bestanden. Sectie Helm toepassen op PitStop bevat meer informatie over charts en bijbehorende templates.

De voordelen van Helm

Configuratie

De services, deployments en overige manifesten voor Kubernetes in .yaml bestanden bevatten veel herhalende tekst.

```yml
# service.yaml

apiVersion: v1
kind: Service
metadata:
name: "my-app"
labels:
    app: "my-app"
spec:
type: LoadBalancer
selector:
    app: "my-app"
ports:
    - protocol: TCP
    name: http
    port: 80
    targetPort: 5000
```

In dit voorbeeld zit ook een deployment:

```yaml
# deployment.yanl

apiVersion: apps/v1
kind: Deployment
metadata:
name: "my-app"
labels:
    app: "my-app"
spec:
template:
    container:
        image: "app/image:4.2.0"
    <verdere spec is weggelaten>
```

De deployment gebruikt dezelfde naam van de applicatie in de .yaml bestand als de service. Klinkt logisch, want het betreft natuurlijk dezelfde applicatie. De naam is echter nu al vijf keer voluit geschreven. Als we nu de naam van de applicatie wijzigen, dan moet dit op veel plekken gebeuren. Helm helpt ons hierbij door een values.yaml bestand te gebruiken waarin het variabelen bijhoudt:

```yml

# values.yaml

name: "my-app" 

deployment:
image: "repo/image"
tag: "4.2.0"

```

De values.yaml neemt nu de naam van de applicatie op als variabele. De gebruikte image voor de deployment is ook opgeslagen onder deployment. Helm injecteert nu deze variabelen in de service.yaml en deployment.yaml bestanden:

```yaml

# service.yaml

apiVersion: v1
kind: Service
metadata:
name: {{ .Values.name }}
labels:
    app: {{ .Values.name }}
spec:
type: LoadBalancer
selector:
    app: {{ .Values.name }}
ports:
    - protocol: TCP
    name: http
    port: 80
    targetPort: 5000

# deployment.yaml

apiVersion: apps/v1
kind: Deployment
metadata:
name: {{ .Values.name }}
labels:
    app: {{ .Values.name }}
spec:
template:
    container:
        image: {{ .Values.deployment.image }}:{{ .Values.deployment.tag }}
    <verdere spec is weggelaten>
```

We hoeven nu maar op één plek de naam te wijzigen.

De gebruikte image in de deployment is nu aangegeven als Values.deployment.image zoals de structuur in het values.yaml bestand is opgebouwd. Dit maakt het mogelijk om eenvoudig en snel wijzigingen toe te passen en te deployen naar Kubernetes. Helm kan nu de gemaakte Chart.yaml eenvoudig hergebruiken met behulp van verschillende value.yaml bestanden om dezelfde applicatie te deployen maar met andere variabelen:

```bash
    helm install [name] [chart] --values <naam van values.yaml>
```

Versiebeheer deployments

Wanneer we deployments uitvoeren met helm install en helm upgrade commandos zal Helm deze configuraties bijhouden in een history. We kunnen nu eenvoudig deployments teruggedraaien als er iets niet goed is. Het commando hiervoor is:

```bash
    helm rollback <release> [revision].
```

Hooks (automatisering)

Helm kan gebruik maken van hooks die triggeren na een bepaalde actie om de automatisering te verhogen. Onderstaand tabel weergeeft de hooks die beschikbaar die Helm aanbiedt.

HookBeschrijving
pre-installUitvoeren na template gerenderd is.
post-installUitvoeren nadat alle resources geladen zijn.
pre-deleteUitvoeren voor het verwijderen.
post-deleteUitvoeren na het verwijderen.
pre-upgradeUitvoeren nadat template gerenderd is.
post-upgradeUitvoeren nadat alle resources geüpdatet zijn.
pre-rollbackUitvoeren nadat template gerenderd is.
post-rollbackUitvoeren nadat alle resources gewijzigd zijn.
testUitvoeren bij test commando.

Meer informatie over hooks voor Helm is te vinden op de website van helm.

Populariteit

Veel gebruikte applicaties zoals MySQL, MongoDB, WordPress etc. hebben een helm chart online. We kunnen deze eenvoudig binnen halen door de volgende commandos uit te voeren:

helm repo add bitnami https://charts.bitnami.com/bitnami

helm install bitnami/wordpress

Helm zal nu de WordPress applicatie die gepackaged is door de chart uploaden naar de Kubernetes cluster. De chart is ook te gebruiken als dependency in een andere chart. De productiviteit gaat hiermee omhoog omdat we minder charts hoeven te maken.

CNCF houdt surveys om te peilen hoe bedrijven gebruik maken van technologieën van CNCF. Helm bleek onder de gevraagden de populairste package manager (Cloud Native Computing Foundation, 2020).

Gebruik Helm Survey
Figuur 1 - Gebruik Helm Survey

Door de populariteit van Helm is er meer zekerheid dat de technologie onderhouden wordt en mee gaat met de tijd. Daarnaast is er veel documentatie te vinden om eventuele problemen op te kunnen lossen, zoals op StackOverflow.

De nadelen van Helm

Het voordeel dat Helm biedt met het hergebruiken van charts kan een nadeel meebrengen. Als er een bug in een geneste chart template zit die in andere applicaties ook gebruikt worden, dan kan het lastig zijn om deze te identificeren en verbeteren.

Verder komt er meer complexiteit kijken bij het opzetten en gebruiken van Helm. Het team moet gewend raken aan de structuur van Helm en de commando's die het met zich mee brengt. Helm kan ook overkill zijn voor een applicatie (Romph, 2020).

Helm toepassen op PitStop

Download Helm op één van de volgende manieren:

  1. Download de binary.
  2. brew install helm (MacOS).
  3. choco install kubernetes-helm (Windows).

Ga naar de kubernetes directory in het project of maak een nieuwe directory. Voer het volgende commando uit:

helm create <chart-name>

Helm maakt nu een nieuwe chart met standaard bestanden in de directory kubernetes/helm zoals te zien is in figuur 2.

Helm directory
Figuur 2 - Helm directory

De charts directory is de plek om geneste charts op te slaan. Het Chart.yaml bestand ziet er als volgt uit:

```yml
# General information
apiVersion: v2
name: pitstop-app
description: A Helm chart for Kubernetes

# A chart can be either an 'application' or a 'library' chart.
# Type chart
type: application

# Chart version
version: 0.1.0

# Application version
appVersion: "1.16.0"

```

InfoSupport heeft een wiki gemaakt op de repo van pitstop om aan te geven welke componenten nodig zijn om PitStop te draaien zonder mesh (Van Wijk, z.d.), zie figuur 3 .

Pitstop no mesh
Figuur 3 - Pitstop no mesh .yaml

Bovenstaande .yaml bestanden zitten in de k8s directory. Helm gebruikt deze bestanden om de templates aan te maken. We kopiëren ze in de helm/templates folder. Helm maakt het nu mogelijk om de PitStop applicatie te draaien in Kubernetes, zonder we dat een .yaml bestand hoeven aan te passen. Dit kan door het volgende commando uit te voeren:

```bash
  helm install <chart-name> <directory-name>
```

We willen variabelen injecteren in de .yaml bestanden die we gekopieerd hebben in de helm/templates folder. Helm kan dit op de volgende manieren:

  1. helm install --set name=value.
  2. values.yaml bestand.

Automatiseren staat centraal in deze minor dus om dit te bevorderen maken we een values.yaml. In dit bestand schrijven we key-value pairs die Helm zal injecteren in de template .yaml bestanden. Als voorbeeld nemen we invoiceservice.yml:

invoiceservice
Figuur 4 - invoiceservice.yaml

We geven de gewenste waardes van de variabelen in de values.yaml weer:

values.yaml invoiceservice
Figuur 5 - values.yaml invoiceservice

We gaan nu de PitStop applicatie draaien in Kubernetes. Dit doen we door het volgende commando uit te voeren:

helm install <chart-name> <directory-name> --values <directory/values.yaml>

We geven de values.yaml bestand mee als optie in het commando zodat Helm deze values injecteert in de templates.

Helm install
Figuur 6 - Helm install --values

Bij het uitvoeren van het commando komen geen foutmeldingen. We controleren of alle containers succesvol draaien:

Kubectl get pods
Figuur 7 - kubectl get pods --namespace pitstop

De PitStop applicatie is nu te openen op port 7000:

Pitstop webapp
Figuur 8 - PitStop webapp port 7000

Wanneer we wijzigingen toebrengen aan de templates of values kunnen we Helm deze wijzigingen laten doorvoeren:

helm upgrade <chart-name> <directory-name>

Helm zal nu de oude pods terminaten en nieuwe opstarten met de nieuwste wijzigingen. Het is eenvoudig om een tweede applicatie ernaast te laten draaien:

helm install pitstop-app-2 pitstop-app --values ./pitstop-app/values.yaml

Helm kan terug naar een oude deployment door het volgende commando uit te voeren:

helm rollback <release> [revision]

Gebruik hierbij het commando helm history <release> om inzicht te krijgen welke versies mogelijk zijn zoals te zien in figuur 9.

Helm history
Figuur 9 - Helm history

Helm alternatieven

Helm heeft niet direct een alternatief voor wat het brengt. Helm is een vrij complexe tool die een hoop te bieden heeft. Er zijn andere tools beschikbaar (Harness, 2021) die beter bij een applicatie passen:

  1. Kustomize - Een configuratie management tool en sinds Kubernetes 1.14 native.
  2. Jsonnet - Een templating taal en engine.
  3. Skaffold - Een Kubernetes management tool met build en deploy componenten.

Conclusie

In dit onderzoek hebben we geleerd dat Helm een package manager is voor Kubernetes en dat het ontwikkelaars én Ops functionaliteit biedt om deployments te versimpelen en automatiseren met behulp van hooks. Het gebruik van Helm voegt enige complexiteit toe en moet de afweging gemaakt worden of de applicatie behoefte heeft aan deze extra laag.

Met het toepassen van de opgedane theorie in een prototype van PitStop is er geleerd hoe we Kubernetes manifest bestanden bundelen tot templates met een bijbehorend values.yaml bestand. Dit bestand zorgt ervoor dat we wijzigen aan deployments eenvoudig, snel en overzichtelijk kunnen maken.

Met behulp van versiebeheer van releases kunnen we eenvoudig teruggeschakelen naar oudere versies van de applicaties. Organisaties bieden populaire applicaties aan als bestaande charts op het internet en deze kunnen we als dependecy/geneste chart gebruiken om werk te versnellen.

Concluderend maakt Helm het maken en uitvoeren van deployments sneller, overzichtelijker, veiliger en geeft mogelijkheid tot meer automatiseren.

Bronnen

Last change: 2025-01-13