Türchen #12: Helm auf bitte - Ein Einstieg in Kubernetes Package-Management


Helm

Helm ist der Kubernetes Package Manager. Mit Helm können Packages - sogenannte Charts - erstellt und gepflegt werden, welche die komplexe Bereitstellung von Ressourcen (Pods, Services, Deployments usw.) vereinfachen soll.

Mit Helm können Packages installiert, Revisionen erstellt und komplexe Änderungen zurückgerollt werden.

Voraussetzungen

Docker mit Kubernetes installieren

Damit wir mit Kubernetes arbeiten können benötigen wir ein installiertes Docker mit aktiven Kubernetes.

Helm installieren

Hier sind die Links zu den Anleitungen für die gängigen Packet Manager:

Erstelle ein Chart

Ein Chart ist zunächst ein Set mit Templates und Dateien mit Variablen, welche die Templates mit Inhalt füllen. Werfen wir einen Blick in ein neues Chart, welches wir nun bauen werden. Hierfür muss Helm bereits installiert sein.

Dazu führen wir folgenden Befehl aus:

➜ helm create erste-app
Creating erste-app

Und schauen uns die Struktur an:

➜ tree erste-app
erste-app
├── Chart.yaml                        <- Chart Definitionen
├── charts                            <- Abhängigkeiten (depending charts)
├── templates                         <- Verzeichnis mot dem Templates für Kubernetes-Manifest
│   ├── NOTES.txt                     <- Textdatei mit Hinweisen, z.B was nach der Installation gemacht werden muss
│   ├── _helpers.tpl                  <-  _Dateien sind nicht im Manifest enthalten
│   ├── deployment.yaml               <- *.yaml Dateien enthalten die Templates
│   ├── ingress.yaml
│   ├── service.yaml
│   └── tests
│       └── test-connection.yaml
└── values.yaml                       <- Default Konfiguration, die Datei wird vom Template geparst

Nach dem wir uns mit der Verzeichnisstruktur beschäftigt haben, betrachten wir die Chart.yaml diese Datei enthält die globalen Chart Definitonen:

➜ cat Chart.yaml
apiVersion: v1                            <- immer "v1"       
appVersion: "1.0"                         <- (optional)
description: A Helm chart for Kubernetes  <- (optional)
name: erste-app                            <- Name des Charts (Voraussetzung)
version: 0.1.0                            <- Eine SemVer 2 Version kompatible Versionsnummer  (Voraussetzung)

Im Verzeichnis templates befidnen sich die *.yaml Templates, mit heml create werden dort standardmässig immer drei YAML-Dateien erstellt deployment.yaml, ingress.yaml und die service.yaml. Alle diese Dateein parsen die values.yaml, wenn das Helm Chart installiert wird.

Deshalb wagen wir einen Blick in die values.yaml

➜ cat values.yaml
# Default values for erste-app.
# This is a YAML-formatted file.
# Declare variables to be passed into your templates.

replicaCount: 1

image:
  repository: nginx
  tag: stable
  pullPolicy: IfNotPresent

imagePullSecrets: []
nameOverride: ""
fullnameOverride: ""

service:
  type: ClusterIP
  port: 80

ingress:
  enabled: false
  annotations: {}
    # kubernetes.io/ingress.class: nginx
    # kubernetes.io/tls-acme: "true"
  hosts:
    - host: chart-example.local
      paths: []

  tls: []
  #  - secretName: chart-example-tls
  #    hosts:
  #      - chart-example.local

resources: {}
  # We usually recommend not to specify default resources and to leave this as a conscious
  # choice for the user. This also increases chances charts run on environments with little
  # resources, such as Minikube. If you do want to specify resources, uncomment the following
  # lines, adjust them as necessary, and remove the curly braces after 'resources:'.
  # limits:
  #   cpu: 100m
  #   memory: 128Mi
  # requests:
  #   cpu: 100m
  #   memory: 128Mi

nodeSelector: {}

tolerations: []

affinity: {}

Wir stellen zunächst fest, dass Helm ein Chart für eine nginx Installation erstellt hat. Hier finden wir auch die Abschnitte für ingress und service wieder.
Gleich werden wir unser Helm Chart installieren, prüfen aber zuvor, ob unser Template sauber ersrtellt wird. Dafür rufen wir Helm mit dem Befehl helm template erste-app auf

➜ helm template erste-app
---
# Source: erste-app/templates/service.yaml
apiVersion: v1
kind: Service
metadata:
  name: release-name-erste-app
  labels:
    app.kubernetes.io/name: erste-app
    helm.sh/chart: erste-app-0.1.0
    app.kubernetes.io/instance: release-name
    app.kubernetes.io/version: "1.0"
    app.kubernetes.io/managed-by: Tiller
spec:
  type: ClusterIP
  ports:
    - port: 80
      targetPort: http
      protocol: TCP
      name: http
  selector:
    app.kubernetes.io/name: erste-app
    app.kubernetes.io/instance: release-name

---
# Source: erste-app/templates/tests/test-connection.yaml
apiVersion: v1
kind: Pod
metadata:
  name: "release-name-erste-app-test-connection"
  labels:
    app.kubernetes.io/name: erste-app
    helm.sh/chart: erste-app-0.1.0
    app.kubernetes.io/instance: release-name
    app.kubernetes.io/version: "1.0"
    app.kubernetes.io/managed-by: Tiller
  annotations:
    "helm.sh/hook": test-success
spec:
  containers:
    - name: wget
      image: busybox
      command: ['wget']
      args:  ['release-name-erste-app:80']
  restartPolicy: Never

---
# Source: erste-app/templates/deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: release-name-erste-app
  labels:
    app.kubernetes.io/name: erste-app
    helm.sh/chart: erste-app-0.1.0
    app.kubernetes.io/instance: release-name
    app.kubernetes.io/version: "1.0"
    app.kubernetes.io/managed-by: Tiller
spec:
  replicas: 1
  selector:
    matchLabels:
      app.kubernetes.io/name: erste-app
      app.kubernetes.io/instance: release-name
  template:
    metadata:
      labels:
        app.kubernetes.io/name: erste-app
        app.kubernetes.io/instance: release-name
    spec:
      containers:
        - name: erste-app
          image: "nginx:stable"
          imagePullPolicy: IfNotPresent
          ports:
            - name: http
              containerPort: 80
              protocol: TCP
          livenessProbe:
            httpGet:
              path: /
              port: http
          readinessProbe:
            httpGet:
              path: /
              port: http
          resources:
            {}


---
# Source: erste-app/templates/ingress.yaml

Nun können wir unser erstes Helm Chart installieren, dies machen wir mit dem Befehl helm install erste-app --name=helm-auf-01.

➜ helm install erste-app --name=helm-auf-01
NAME:   helm-auf-01
LAST DEPLOYED: Wed Dec 11 09:32:05 2019
NAMESPACE: default
STATUS: DEPLOYED

RESOURCES:
==> v1/Deployment
NAME                   READY  UP-TO-DATE  AVAILABLE  AGE
helm-auf-01-erste-app  0/1    1           0          0s

==> v1/Pod(related)
NAME                                   READY  STATUS             RESTARTS  AGE
helm-auf-01-erste-app-77757b486-mpbjz  0/1    ContainerCreating  0         0s

==> v1/Service
NAME                   TYPE       CLUSTER-IP     EXTERNAL-IP  PORT(S)  AGE
helm-auf-01-erste-app  ClusterIP  10.108.143.11  <none>       80/TCP   0s


NOTES:
1. Get the application URL by running these commands:
  export POD_NAME=$(kubectl get pods --namespace default -l "app.kubernetes.io/name=erste-app,app.kubernetes.io/instance=helm-auf-01" -o jsonpath="{.items[0].metadata.name}")
  echo "Visit http://127.0.0.1:8080 to use your application"
  kubectl port-forward $POD_NAME 8080:80

Am Ende der Ausführung gibt dir Helm noch einige Hinweise mit, diese solltest du beachten, damit wir uns die WebSite per curl http://127.0.0.1:8080/ ansehen können.

➜ curl http://127.0.0.1:8080/
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
<style>
    body {
        width: 35em;
        margin: 0 auto;
        font-family: Tahoma, Verdana, Arial, sans-serif;
    }
</style>
</head>
<body>
<h1>Welcome to nginx!</h1>
<p>If you see this page, the nginx web server is successfully installed and
working. Further configuration is required.</p>

<p>For online documentation and support please refer to
<a href="http://nginx.org/">nginx.org</a>.<br/>
Commercial support is available at
<a href="http://nginx.com/">nginx.com</a>.</p>

<p><em>Thank you for using nginx.</em></p>
</body>
</html>

Zurück zu den Blogbeiträgen

Trainings und Workshops

Vom Kurs für Einsteiger bis hin zu Experten-Workshops mit Tiefgang können wir Euch mit technischen Trainings unterstützen. Darüber hinaus bieten wir auch Workshops mit Fokus auf Cloud-Strategie oder für die Vertriebsmannschaft an.

Mehr...