Mit Helm und Kubernetes

1. Übersicht

Helm ist Paketmanager für Kubernetes-Anwendungen . In diesem Tutorial lernen wir die Grundlagen von Helm kennen und wie sie ein leistungsstarkes Werkzeug für die Arbeit mit Kubernetes-Ressourcen bilden.

In den letzten Jahren ist Kubernetes enorm gewachsen, ebenso wie das Ökosystem, das es unterstützt. Vor kurzem wurde Helm von der Cloud Native Computing Foundation (CNCF) als Inkubationsprojekt angekündigt, was seine wachsende Beliebtheit bei Kubernetes-Benutzern zeigt.

2. Hintergrund

Obwohl diese Begriffe heutzutage ziemlich häufig sind, insbesondere bei Personen, die mit Cloud-Technologien arbeiten, sollten wir sie für diejenigen, die es nicht wissen, schnell durchgehen:

  1. Container: Container bezieht sich auf die Virtualisierung auf Betriebssystemebene . Innerhalb eines Betriebssystems werden mehrere Container in isolierten Benutzerbereichen ausgeführt. Programme, die in einem Container ausgeführt werden, haben nur Zugriff auf Ressourcen, die dem Container zugewiesen sind.
  2. Docker: Docker ist ein beliebtes Programm zum Erstellen und Ausführen von Containern . Es wird mit Docker Daemon geliefert, dem Hauptprogramm zur Verwaltung von Containern. Docker Daemon bietet Zugriff auf seine Funktionen über die Docker Engine-API, die von der Docker Command-Line Interface (CLI) verwendet wird. In diesem Artikel finden Sie eine detailliertere Beschreibung von Docker.
  3. Kubernetes: Kubernetes ist ein beliebtes Container-Orchestrierungsprogramm . Obwohl Docker für die Arbeit mit verschiedenen Containern ausgelegt ist, wird es am häufigsten verwendet. Es bietet eine große Auswahl an Funktionen, einschließlich Bereitstellungsautomatisierung, Skalierung und Vorgängen in einem Cluster von Hosts. In diesem Artikel wird Kubernetes zur weiteren Bezugnahme hervorragend behandelt.

3. Helmarchitektur

Helm hat eine ziemlich einfache Architektur, die aus einem Client und einem In-Cluster-Server besteht:

  • Tiller Server: Helm verwaltet die Kubernetes-Anwendung über eine Komponente namens Tiller Server, die in einem Kubernates-Cluster installiert ist. Tiller interagiert mit dem Kubernetes-API-Server, um Kubernetes-Ressourcen zu installieren, zu aktualisieren, abzufragen und zu entfernen.
  • Helm-Client: Helm bietet eine Befehlszeilenschnittstelle, über die Benutzer mit Helm-Diagrammen arbeiten können . Helm Client ist für die Interaktion mit dem Tiller Server verantwortlich, um verschiedene Vorgänge wie Installations-, Upgrade- und Rollback-Diagramme auszuführen.

4. Helmkarten

Helm verwaltet Kubernetes-Ressourcenpakete über Diagramme .

Wir werden in Kürze mehr über Diagramme erfahren, wenn wir sie erstellen. Derzeit ist ein Diagramm jedoch nur eine Reihe von Informationen, die zum Erstellen einer Kubernetes-Anwendung in einem Kubernetes-Cluster erforderlich sind:

  • Ein Diagramm ist eine Sammlung von Dateien, die in einer bestimmten Verzeichnisstruktur organisiert sind
  • Die Konfigurationsinformationen zu einem Diagramm werden in der Konfiguration verwaltet
  • Schließlich wird eine laufende Instanz eines Diagramms mit einer bestimmten Konfiguration als Release bezeichnet

5. Einrichtung

Wir müssen ein paar Dinge im Voraus einrichten, damit wir unsere erste Helmkarte entwickeln können.

Um mit Helm arbeiten zu können, benötigen wir zunächst einen Kubernetes-Cluster. Für dieses Tutorial verwenden wir Minikube, das eine hervorragende Möglichkeit bietet, lokal mit einem Kubernetes-Cluster mit einem Knoten lokal zu arbeiten . Unter Windows ist es jetzt möglich, Hyper-V als nativen Hypervisor zum Ausführen von Minikube zu verwenden. Weitere Informationen zum Einrichten von Minikube finden Sie in diesem Artikel.

Für die Verwaltung im Kubernetes-Cluster benötigen wir eine Basisanwendung. In diesem Tutorial verwenden wir eine einfache Spring Boot-Anwendung, die als Docker-Container verpackt ist. Eine ausführlichere Beschreibung zum Packen einer solchen Anwendung als Docker-Container finden Sie in diesem Artikel.

6. Helm installieren

Es gibt verschiedene Möglichkeiten, Helm zu installieren, die auf der offiziellen Installationsseite von Helm genau beschrieben sind. Der schnellste Weg, um helm unter Windows zu installieren, ist die Verwendung von Chocolaty , einem Paketmanager für Windows-Plattformen.

Mit Chocolaty ist es ein einfacher einzeiliger Befehl, Helm zu installieren:

choco install kubernetes-helm

Dadurch wird der Helm-Client lokal installiert.

Jetzt müssen wir die Helm-CLI initialisieren, die den Tiller-Server effektiv auch auf einem Kubernetes-Cluster installiert, wie in der Kubernetes-Konfiguration angegeben. Stellen Sie sicher, dass der Kubernetes-Cluster ausgeführt wird und über kubectl zugänglich ist, bevor Sie Helm initialisieren :

kubectl cluster-info

Und dann können wir Helm über die Helm-CLI selbst initialisieren:

helm init

7. Entwicklung unseres ersten Diagramms

Jetzt sind wir bereit, unser erstes Helmdiagramm mit Vorlagen und Werten zu entwickeln.

7.1. Erstellen eines Diagramms

Die zuvor installierte Helm-CLI ist sehr praktisch beim Erstellen eines Diagramms :

helm create hello-world

Bitte beachten Sie, dass der Name des hier angegebenen Diagramms der Name des Verzeichnisses ist, in dem das Diagramm erstellt und gespeichert wird.

Lassen Sie uns schnell die für uns erstellte Verzeichnisstruktur sehen:

hello-world / Chart.yaml values.yaml templates / charts / .helmignore

Lassen Sie uns die Relevanz dieser für uns erstellten Dateien und Ordner verstehen:

  • Chart.yaml : Dies ist die Hauptdatei, die die Beschreibung unseres Diagramms enthält
  • values.yaml : Dies ist die Datei, die die Standardwerte für unser Diagramm enthält
  • Vorlagen : Dies ist das Verzeichnis, in dem Kubernetes-Ressourcen als Vorlagen definiert sind
  • Diagramme : Dies ist ein optionales Verzeichnis, das Unterdiagramme enthalten kann
  • .helmignore: This is where we can define patterns to ignore when packaging (similar in concept to .gitignore)

7.2. Creating Template

If we see inside the template directory, we'll notice that few templates for common Kubernetes resources have already been created for us:

hello-world / templates / deployment.yaml service.yaml ingress.yaml ......

We may need some of these and possibly other resources in our application, which we'll have to create ourselves as templates.

For this tutorial, we'll create deployment and a service to expose that deployment. Please note the emphasis here is not to understand Kubernetes in detail. Hence we'll keep these resources as simple as possible.

Let's edit the file deployment.yaml inside the templates directory to look like:

apiVersion: apps/v1 kind: Deployment metadata: name: {{ include "hello-world.fullname" . }} labels: app.kubernetes.io/name: {{ include "hello-world.name" . }} helm.sh/chart: {{ include "hello-world.chart" . }} app.kubernetes.io/instance: {{ .Release.Name }} app.kubernetes.io/managed-by: {{ .Release.Service }} spec: replicas: {{ .Values.replicaCount }} selector: matchLabels: app.kubernetes.io/name: {{ include "hello-world.name" . }} app.kubernetes.io/instance: {{ .Release.Name }} template: metadata: labels: app.kubernetes.io/name: {{ include "hello-world.name" . }} app.kubernetes.io/instance: {{ .Release.Name }} spec: containers: - name: {{ .Chart.Name }} image: "{{ .Values.image.repository }}:{{ .Values.image.tag }}" imagePullPolicy: {{ .Values.image.pullPolicy }} ports: - name: http containerPort: 8080 protocol: TCP

Similarly, let's edit the file service.yaml to look like:

apiVersion: v1 kind: Service metadata: name: {{ include "hello-world.fullname" . }} labels: app.kubernetes.io/name: {{ include "hello-world.name" . }} helm.sh/chart: {{ include "hello-world.chart" . }} app.kubernetes.io/instance: {{ .Release.Name }} app.kubernetes.io/managed-by: {{ .Release.Service }} spec: type: {{ .Values.service.type }} ports: - port: {{ .Values.service.port }} targetPort: http protocol: TCP name: http selector: app.kubernetes.io/name: {{ include "hello-world.name" . }} app.kubernetes.io/instance: {{ .Release.Name }}

Now, with our knowledge of Kubernetes, these template files look quite familiar except for some oddities. Note the liberal usage of text within double parentheses {{}}. This is what is called a template directive.

Helm makes use of the Go template language and extends that to something called Helm template language. During the evaluation, every file inside the template directory is submitted to the template rendering engine. This is where the template directive injects actual values in the templates.

7.3. Providing Values

In the previous sub-section, we saw how to use the template directive in our templates. Now, let's understand how we can pass values to the template rendering engine. We typically pass values through Built-in Objects in Helm.

There are many such objects available in Helm, like Release, Values, Chart, and Files.

We can use the file values.yaml in our chart to pass values to the template rendering engine through the Built-in Object Values. Let's modify the values.yaml to look like:

replicaCount: 1 image: repository: "hello-world" tag: "1.0" pullPolicy: IfNotPresent service: type: NodePort port: 80

However, note how these values have been accessed within templates using dots separating namespaces. We have used the image repository and tag as “hello-world” and “1.0”, this must match the docker image tag we created for our Spring Boot application.

8. Understanding Helm Commands

With everything done so far, we're now ready to play with our chart. Let's see what are the different commands available in Helm CLI to make this fun!

8.1. Helm Lint

Firstly, this is a simple command that takes the path to a chart and runs a battery of tests to ensure that the chart is well-formed:

helm lint ./hello-world ==> Linting ./hello-world 1 chart(s) linted, no failures

8.2 Helm Template

Also, we have this command to render the template locally, without a Tiller Server, for quick feedback:

helm template ./hello-world --- # Source: hello-world/templates/service.yaml apiVersion: v1 kind: Service metadata: name: release-name-hello-world labels: app.kubernetes.io/name: hello-world helm.sh/chart: hello-world-0.1.0 app.kubernetes.io/instance: release-name app.kubernetes.io/managed-by: Tiller spec: type: NodePort ports: - port: 80 targetPort: http protocol: TCP name: http selector: app.kubernetes.io/name: hello-world app.kubernetes.io/instance: release-name --- # Source: hello-world/templates/deployment.yaml apiVersion: apps/v1 kind: Deployment metadata: name: release-name-hello-world labels: app.kubernetes.io/name: hello-world helm.sh/chart: hello-world-0.1.0 app.kubernetes.io/instance: release-name app.kubernetes.io/managed-by: Tiller spec: replicas: 1 selector: matchLabels: app.kubernetes.io/name: hello-world app.kubernetes.io/instance: release-name template: metadata: labels: app.kubernetes.io/name: hello-world app.kubernetes.io/instance: release-name spec: containers: - name: hello-world image: "hello-world:1.0" imagePullPolicy: IfNotPresent ports: - name: http containerPort: 8080 protocol: TCP

8.3. Helm Install

Once we've verified the chart to be fine, finally, we can run this command to install the chart into the Kubernetes cluster:

helm install --name hello-world ./hello-world NAME: hello-world LAST DEPLOYED: Mon Feb 25 15:29:59 2019 NAMESPACE: default STATUS: DEPLOYED RESOURCES: ==> v1/Service NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE hello-world NodePort 10.110.63.169  80:30439/TCP 1s ==> v1/Deployment NAME DESIRED CURRENT UP-TO-DATE AVAILABLE AGE hello-world 1 0 0 0 1s ==> v1/Pod(related) NAME READY STATUS RESTARTS AGE hello-world-7758b9cdf8-cs798 0/1 Pending 0 0s

Finally, note that we have named the release of this chart with the flag –name. The command responds with the summary of Kubernetes resources created in the process.

8.4. Helm Get

Now, we would like to see which charts are installed as what release. This command lets us query the named releases:

helm ls --all NAME REVISION UPDATED STATUS CHART APP VERSION NAMESPACE hello-world 1 Mon Feb 25 15:29:59 2019 DEPLOYED hello-world-0.1.0 1.0 default

8.5. Helm Upgrade

What if we have modified our chart and need to install the updated version? This command helps us to upgrade a release to a specified or current version of the chart or configuration:

helm upgrade hello-world ./hello-world Release "hello-world" has been upgraded. Happy Helming! LAST DEPLOYED: Mon Feb 25 15:36:04 2019 NAMESPACE: default STATUS: DEPLOYED RESOURCES: ==> v1/Service NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE hello-world NodePort 10.110.63.169  80:30439/TCP 6m5s ==> v1/Deployment NAME DESIRED CURRENT UP-TO-DATE AVAILABLE AGE hello-world 1 1 1 1 6m5s ==> v1/Pod(related) NAME READY STATUS RESTARTS AGE hello-world-7758b9cdf8-cs798 1/1 Running 0 6m4s

8.6. Helm Rollback

It can always happen that a release went wrong and needs to be taken back. This is the command to rollback a release to the previous version:

helm rollback hello-world 1 Rollback was a success! Happy Helming!

8.7. Helm Delete

Although less likely, we may want to delete a release completely. We can use this command to delete a release from Kubernetes:

helm delete --purge hello-world release "hello-world" deleted

These are only some of the commands available to work with charts and releases in Helm.

9. Distributing Charts

While templating is a powerful tool that Helm brings to the world of managing Kubernetes resources, it's not the only benefit of using Helm. As we saw in the previous section, Helm acts as a package manager for the Kubernetes application and makes installing, querying, upgrading, and deleting releases pretty seamless.

In addition to this, Helm comes with commands as part of its CLI to package, publish, and fetch Kubernetes applications as charts:

9.1. Helm Package

Firstly, we need to package the charts we have created to be able to distribute them. This is the command to create versioned archive files of the chart:

helm package ./hello-world Successfully packaged chart and saved it to: \hello-world\hello-world-0.1.0.tgz

Note that it produces an archive on your machine that can be distributed manually or through public or private chart repositories.

9.2. Helm Repo

Finally, we need a mechanism to work with shared repositories to collaborate. Repo bundles a bunch of commands that we can use to add, remove, list, or index chart repositories. Let's see how we can use them.

We can create a git repository and use that to function as our chart repository. The only requirement is that it should have an index.yaml file.

We can create index.yaml for our chart repo:

helm repo index my-repo/ --url //.github.io/my-repo

This generates the index.yaml file, which we should push to the repository along with the chart archives.

After successfully creating the chart repository, subsequently, we can remotely add this repo:

helm repo add my-repo //my-pages.github.io/my-repo

Now, we should be able to install the charts from our repo directly:

helm install my-repo/hello-world --name=hello-world

There are quite some utility commands available to work with chart repositories.

10. Schlussfolgerung

Zusammenfassend haben wir in diesem Tutorial die Kernkomponenten von Helm, einem Paketmanager für Kubernetes-Anwendungen, besprochen. Wir haben die Optionen zur Installation von Helm verstanden. Darüber hinaus haben wir ein Beispieldiagramm und Vorlagen mit Werten erstellt.

Anschließend haben wir mehrere Befehle durchlaufen, die als Teil der Helm-CLI verfügbar sind, um die Kubernetes-Anwendung als Helm-Paket zu verwalten.

Schließlich haben wir die Optionen für die Verteilung von Helm-Paketen über Repositorys erörtert.