Usar Helm y Kubernetes

1. Información general

Helm es un administrador de paquetes para aplicaciones de Kubernetes . En este tutorial, comprenderemos los conceptos básicos de Helm y cómo forman una herramienta poderosa para trabajar con los recursos de Kubernetes.

En los últimos años, Kubernetes ha crecido enormemente, al igual que el ecosistema que lo respalda. Recientemente, Helm ha sido anunciado como un proyecto de incubación por Cloud Native Computing Foundation (CNCF), lo que demuestra su creciente popularidad entre los usuarios de Kubernetes.

2. Fondo

Aunque estos términos son bastante comunes en estos días, particularmente entre quienes trabajan con tecnologías en la nube, repasemos rápidamente para aquellos que no lo saben:

  1. Contenedor: contenedor se refiere a la virtualización a nivel de sistema operativo . Varios contenedores se ejecutan dentro de un sistema operativo en espacios de usuario aislados. Los programas que se ejecutan dentro de un contenedor solo tienen acceso a los recursos asignados al contenedor.
  2. Docker: Docker es un programa popular para crear y ejecutar contenedores . Viene con Docker Daemon, que es el programa principal que administra contenedores. Docker Daemon ofrece acceso a sus funciones a través de la API de Docker Engine, que utiliza la interfaz de línea de comandos de Docker (CLI). Consulte este artículo para obtener una descripción más detallada de Docker.
  3. Kubernetes: Kubernetes es un popular programa de orquestación de contenedores . Aunque está diseñado para funcionar con diferentes contenedores, Docker se usa con mayor frecuencia. Ofrece una amplia selección de funciones, incluida la automatización de la implementación, el escalado y las operaciones en un grupo de hosts. Hay una excelente cobertura de Kubernetes en este artículo para mayor referencia.

3. Arquitectura del timón

Helm tiene una arquitectura bastante simple, que se compone de un cliente y un servidor en el clúster:

  • Tiller Server: Helm administra la aplicación de Kubernetes a través de un componente llamado Tiller Server instalado dentro de un clúster de Kubernetes. Tiller interactúa con el servidor API de Kubernetes para instalar, actualizar, consultar y eliminar recursos de Kubernetes.
  • Cliente de Helm: Helm proporciona una interfaz de línea de comandos para que los usuarios trabajen con Helm Charts . Helm Client es responsable de interactuar con Tiller Server para realizar diversas operaciones como instalar, actualizar y deshacer gráficos.

4. Cuadros de timón

Helm administra los paquetes de recursos de Kubernetes a través de gráficos .

Veremos más sobre gráficos a medida que los creamos en breve, pero por ahora, un gráfico no es más que un conjunto de información necesaria para crear una aplicación de Kubernetes, dado un clúster de Kubernetes:

  • Un gráfico es una colección de archivos organizados en una estructura de directorio específica.
  • La información de configuración relacionada con un gráfico se gestiona en la configuración
  • Finalmente, una instancia en ejecución de un gráfico con una configuración específica se denomina versión.

5. Configuración

Necesitaremos configurar algunas cosas de antemano para poder desarrollar nuestro primer gráfico de timón.

En primer lugar, para comenzar a trabajar con Helm, necesitamos un clúster de Kubernetes. Para este tutorial, usaremos Minikube, que ofrece una excelente manera de trabajar con un clúster de Kubernetes de un solo nodo de forma local . En Windows, ahora es posible usar Hyper-V como el hipervisor nativo para ejecutar Minikube. Consulte este artículo para comprender la configuración de Minikube con más detalles.

Y necesitaremos una aplicación básica para administrar dentro del clúster de Kubernetes. Para este tutorial, usaremos una aplicación Spring Boot simple empaquetada como un contenedor Docker. Para obtener una descripción más detallada de cómo empaquetar una aplicación como un contenedor Docker, consulte este artículo.

6. Instalación de Helm

Hay varias formas de instalar Helm que se describen detalladamente en la página de instalación oficial de Helm. La forma más rápida de instalar helm en Windows es utilizando Chocolaty , un administrador de paquetes para plataformas Windows.

Usando Chocolaty, es un comando simple de una línea para instalar Helm:

choco install kubernetes-helm

Esto instala el cliente de Helm localmente.

Ahora, necesitamos inicializar la CLI de Helm, que efectivamente también instala el servidor Tiller en un clúster de Kubernetes tal como se identifica a través de la configuración de Kubernetes. Por favor asegúrese de que el clúster Kubernetes está en funcionamiento y accesible a través de kubectl antes de inicializar el timón :

kubectl cluster-info

Y luego, podemos inicializar Helm a través de la propia CLI de Helm:

helm init

7. Desarrollando nuestro primer gráfico

Ahora estamos listos para desarrollar nuestro primer Helm Chart con plantillas y valores.

7.1. Crear un gráfico

Helm CLI, que instalamos anteriormente, es bastante útil para crear un gráfico :

helm create hello-world

Tenga en cuenta que el nombre del gráfico proporcionado aquí será el nombre del directorio donde se crea y almacena el gráfico .

Veamos rápidamente la estructura de directorios creada para nosotros:

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

Entendamos la relevancia de estos archivos y carpetas creados para nosotros:

  • Chart.yaml : este es el archivo principal que contiene la descripción de nuestro gráfico
  • values.yaml : este es el archivo que contiene los valores predeterminados para nuestro gráfico
  • templates : este es el directorio donde los recursos de Kubernetes se definen como plantillas
  • gráficos : este es un directorio opcional que puede contener sub-gráficos
  • .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. Conclusión

En resumen, en este tutorial, analizamos los componentes centrales de Helm, un administrador de paquetes para aplicaciones de Kubernetes. Entendimos las opciones para instalar Helm. Además, pasamos por la creación de un gráfico de muestra y plantillas con valores.

Luego, revisamos varios comandos disponibles como parte de la CLI de Helm para administrar la aplicación Kubernetes como un paquete de Helm.

Finalmente, discutimos las opciones para distribuir paquetes Helm a través de repositorios.