Utilizzo di Helm e Kubernetes

1. Panoramica

Helm è un gestore di pacchetti per le applicazioni Kubernetes . In questo tutorial, comprenderemo le basi di Helm e come formano un potente strumento per lavorare con le risorse Kubernetes.

Negli ultimi anni, Kubernetes è cresciuto enormemente, così come l'ecosistema che lo supporta. Di recente, Helm è stato annunciato come progetto di incubazione dalla Cloud Native Computing Foundation (CNCF), che mostra la sua crescente popolarità tra gli utenti di Kubernetes.

2. Sfondo

Sebbene questi termini siano abbastanza comuni in questi giorni, in particolare tra coloro che lavorano con le tecnologie cloud, esaminiamoli rapidamente per coloro che non lo sanno:

  1. Contenitore: il contenitore si riferisce alla virtualizzazione a livello di sistema operativo . Più contenitori vengono eseguiti all'interno di un sistema operativo in spazi utente isolati. I programmi in esecuzione all'interno di un contenitore hanno accesso solo alle risorse assegnate al contenitore.
  2. Docker: Docker è un popolare programma per creare ed eseguire container . Viene fornito con Docker Daemon, che è il programma principale che gestisce i contenitori. Docker Daemon offre l'accesso alle sue funzionalità tramite l'API Docker Engine, che viene utilizzata dall'interfaccia della riga di comando (CLI) Docker. Fare riferimento a questo articolo per una descrizione più dettagliata di Docker.
  3. Kubernetes: Kubernetes è un popolare programma di orchestrazione di contenitori . Sebbene sia progettato per funzionare con diversi contenitori, Docker viene spesso utilizzato. Offre un'ampia selezione di funzionalità tra cui automazione della distribuzione, scalabilità e operazioni su un cluster di host. C'è un'eccellente copertura di Kubernetes in questo articolo per ulteriori riferimenti.

3. Architettura del timone

Helm ha un'architettura abbastanza semplice, composta da un client e un server in cluster:

  • Tiller Server: Helm gestisce l'applicazione Kubernetes tramite un componente chiamato Tiller Server installato all'interno di un cluster Kubernates. Tiller interagisce con il server API Kubernetes per installare, aggiornare, interrogare e rimuovere le risorse Kubernetes.
  • Client Helm: Helm fornisce un'interfaccia della riga di comando per consentire agli utenti di lavorare con Helm Charts . Il client Helm è responsabile dell'interazione con il server Tiller per eseguire varie operazioni come i grafici di installazione, aggiornamento e rollback.

4. Grafici del timone

Helm gestisce i pacchetti di risorse Kubernetes tramite i grafici .

Vedremo di più sui grafici man mano che li creiamo a breve, ma per ora un grafico non è altro che un insieme di informazioni necessarie per creare un'applicazione Kubernetes, dato un cluster Kubernetes:

  • Un grafico è una raccolta di file organizzati in una struttura di directory specifica
  • Le informazioni di configurazione relative a un grafico vengono gestite nella configurazione
  • Infine, un'istanza in esecuzione di un grafico con una configurazione specifica è chiamata release

5. Installazione

Avremo bisogno di alcune cose da impostare in anticipo per sviluppare la nostra prima carta del timone.

Innanzitutto, per iniziare a lavorare con Helm, abbiamo bisogno di un cluster Kubernetes. Per questo tutorial, utilizzeremo Minikube, che offre un modo eccellente per lavorare con un cluster Kubernetes a nodo singolo in locale . Su Windows, ora è possibile utilizzare Hyper-V come Hypervisor nativo per eseguire Minikube. Fare riferimento a questo articolo per comprendere la configurazione di Minikube in modo più dettagliato.

E avremo bisogno di un'applicazione di base da gestire all'interno del cluster Kubernetes. Per questo tutorial, useremo una semplice applicazione Spring Boot confezionata come contenitore Docker. Per una descrizione più dettagliata di come creare un pacchetto di un'applicazione di questo tipo come contenitore Docker, fare riferimento a questo articolo.

6. Installazione di Helm

Esistono diversi modi per installare Helm che sono descritti in modo chiaro nella pagina di installazione ufficiale di Helm. Il modo più rapido per installare helm su Windows è utilizzare Chocolaty , un gestore di pacchetti per piattaforme Windows.

Utilizzando Chocolaty, è un semplice comando di una riga per installare Helm:

choco install kubernetes-helm

Questo installa il client Helm in locale.

Ora, dobbiamo inizializzare la CLI di Helm, che installa efficacemente anche il server Tiller su un cluster Kubernetes come identificato tramite la configurazione Kubernetes. Si prega di accertarsi che il cluster kubernetes è in esecuzione e accessibile attraverso kubectl prima di inizializzare Helm :

kubectl cluster-info

Quindi, possiamo inizializzare Helm tramite la stessa CLI di Helm:

helm init

7. Sviluppare il nostro primo grafico

Ora siamo pronti per sviluppare il nostro primo grafico Helm con modelli e valori.

7.1. Creazione di un grafico

Helm CLI, che abbiamo installato in precedenza, è molto utile nella creazione di un grafico :

helm create hello-world

Si noti che il nome del grafico fornito qui sarà il nome della directory in cui viene creato e archiviato il grafico .

Vediamo rapidamente la struttura delle directory creata per noi:

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

Comprendiamo la rilevanza di questi file e cartelle creati per noi:

  • Chart.yaml : questo è il file principale che contiene la descrizione del nostro grafico
  • values.yaml : questo è il file che contiene i valori predefiniti per il nostro grafico
  • modelli : questa è la directory in cui le risorse Kubernetes sono definite come modelli
  • grafici : questa è una directory opzionale che può contenere sotto-grafici
  • .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. Conclusione

Per riassumere, in questo tutorial, abbiamo discusso i componenti principali di Helm, un gestore di pacchetti per le applicazioni Kubernetes. Abbiamo compreso le opzioni per installare Helm. Inoltre, abbiamo creato un grafico di esempio e modelli con valori.

Quindi, abbiamo esaminato più comandi disponibili come parte della CLI di Helm per gestire l'applicazione Kubernetes come pacchetto Helm.

Infine, abbiamo discusso le opzioni per la distribuzione dei pacchetti Helm attraverso i repository.