Utiliser Helm et Kubernetes

1. Vue d'ensemble

Helm est un gestionnaire de packages pour les applications Kubernetes . Dans ce didacticiel, nous allons comprendre les bases de Helm et comment ils forment un outil puissant pour travailler avec les ressources Kubernetes.

Au cours des dernières années, Kubernetes s'est considérablement développé, tout comme l'écosystème qui le soutient. Récemment, Helm a été annoncé comme un projet d'incubation par la Cloud Native Computing Foundation (CNCF), ce qui montre sa popularité croissante parmi les utilisateurs de Kubernetes.

2. Arrière plan

Bien que ces termes soient assez courants de nos jours, en particulier parmi ceux qui travaillent avec les technologies cloud, parcourons-les rapidement pour ceux qui ne le savent pas:

  1. Conteneur: le conteneur fait référence à la virtualisation au niveau du système d'exploitation . Plusieurs conteneurs s'exécutent dans un système d'exploitation dans des espaces utilisateur isolés. Les programmes exécutés dans un conteneur ont accès uniquement aux ressources affectées au conteneur.
  2. Docker: Docker est un programme populaire pour créer et exécuter des conteneurs . Il est livré avec Docker Daemon, qui est le principal programme de gestion des conteneurs. Docker Daemon offre un accès à ses fonctionnalités via l'API Docker Engine, qui est utilisée par l'interface de ligne de commande (CLI) Docker. Veuillez vous référer à cet article pour une description plus détaillée de Docker.
  3. Kubernetes: Kubernetes est un programme d'orchestration de conteneurs populaire . Bien qu'il soit conçu pour fonctionner avec différents conteneurs, Docker est le plus souvent utilisé. Il offre une large sélection de fonctionnalités, notamment l'automatisation du déploiement, la mise à l'échelle et les opérations sur un cluster d'hôtes. Il existe une excellente couverture de Kubernetes dans cet article pour référence ultérieure.

3. Architecture de la barre

Helm a une architecture assez simple, qui comprend un client et un serveur en cluster:

  • Tiller Server: Helm gère l'application Kubernetes via un composant appelé Tiller Server installé dans un cluster Kubernates. Tiller interagit avec le serveur d'API Kubernetes pour installer, mettre à niveau, interroger et supprimer des ressources Kubernetes.
  • Helm Client: Helm fournit une interface de ligne de commande permettant aux utilisateurs de travailler avec les graphiques Helm . Helm Client est responsable de l'interaction avec le serveur Tiller pour effectuer diverses opérations telles que les graphiques d'installation, de mise à niveau et de restauration.

4. Tableaux de barre

Helm gère les packages de ressources Kubernetes via des graphiques .

Nous en verrons plus sur les graphiques au fur et à mesure que nous les créerons sous peu, mais pour l'instant, un graphique n'est rien d'autre qu'un ensemble d'informations nécessaires pour créer une application Kubernetes, étant donné un cluster Kubernetes:

  • Un graphique est un ensemble de fichiers organisés dans une structure de répertoires spécifique
  • Les informations de configuration liées à un diagramme sont gérées dans la configuration
  • Enfin, une instance en cours d'exécution d'un graphique avec une configuration spécifique est appelée une version

5. Mise en place

Nous aurons besoin de quelques éléments à configurer à l'avance pour que nous puissions développer notre premier Helm Chart.

Premièrement, pour commencer à travailler avec Helm, nous avons besoin d'un cluster Kubernetes. Pour ce didacticiel, nous utiliserons Minikube, qui offre un excellent moyen de travailler localement avec un cluster Kubernetes à nœud unique . Sous Windows, il est désormais possible d'utiliser Hyper-V comme hyperviseur natif pour exécuter Minikube. Reportez-vous à cet article pour comprendre la configuration de Minikube plus en détail.

Et nous aurons besoin d'une application de base à gérer au sein du cluster Kubernetes. Pour ce didacticiel, nous utiliserons une simple application Spring Boot conditionnée en tant que conteneur Docker. Pour une description plus détaillée de la façon de conditionner une telle application en tant que conteneur Docker, reportez-vous à cet article.

6. Installation de Helm

Il existe plusieurs façons d'installer Helm qui sont clairement décrites sur la page d'installation officielle sur Helm. Le moyen le plus rapide d'installer helm sur Windows consiste à utiliser Chocolaty , un gestionnaire de packages pour les plates-formes Windows.

En utilisant Chocolaty, c'est une simple commande en une ligne pour installer Helm:

choco install kubernetes-helm

Cela installe le client Helm localement.

À présent, nous devons initialiser Helm CLI, qui installe également le serveur Tiller sur un cluster Kubernetes tel qu'identifié via la configuration Kubernetes. Veuillez vous assurer que le cluster Kubernetes est en cours d'exécution et accessible via kubectl avant d'initialiser Helm :

kubectl cluster-info

Et puis, nous pouvons initialiser Helm via la CLI Helm elle-même:

helm init

7. Élaboration de notre premier graphique

Nous sommes maintenant prêts à développer notre premier Helm Chart avec des modèles et des valeurs.

7.1. Créer un graphique

Helm CLI, que nous avons installé précédemment, est assez pratique pour créer un graphique :

helm create hello-world

Veuillez noter que le nom du graphique fourni ici sera le nom du répertoire dans lequel le graphique est créé et stocké.

Voyons rapidement la structure de répertoires créée pour nous:

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

Comprenons la pertinence de ces fichiers et dossiers créés pour nous:

  • Chart.yaml : C'est le fichier principal qui contient la description de notre graphique
  • values.yaml : c'est le fichier qui contient les valeurs par défaut de notre graphique
  • templates : il s'agit du répertoire dans lequel les ressources Kubernetes sont définies en tant que modèles
  • graphiques : il s'agit d'un répertoire facultatif pouvant contenir des sous-graphiques
  • .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. Conclusion

Pour résumer, dans ce didacticiel, nous avons abordé les principaux composants de Helm, un gestionnaire de packages pour les applications Kubernetes. Nous avons compris les options pour installer Helm. De plus, nous avons créé un exemple de graphique et des modèles avec des valeurs.

Ensuite, nous sommes passés par plusieurs commandes disponibles dans le cadre de Helm CLI pour gérer l'application Kubernetes en tant que package Helm.

Enfin, nous avons discuté des options de distribution des packages Helm via des référentiels.