lunes, 26 de agosto de 2024

Helm Charts: Empaquetando tu aplicación


Seguimos con nuestro primer Helm Chart. Ya en el [anterior post](https://www.ahioros.info/2024/08/helm-el-manejador-de-paquetes-de.html) te enseñe como instalar helm y tus primeros pasos.

## Creación de un Chart

En este paso, crearemos un Chart para nuestra aplicación. Hacemos esto a traves de la herramienta [Helm](https://helm.sh/).


```bash
helm create nginx-chart
```


Esto nos genera la siguiente estructura de directorios y archivos:


donde:
 - values.yaml es para las configuraciones de la aplicación.
 - Chart.yaml son los metadatos del Chart (como la versión del paquete y el nombre del paquete, etc.).
 - charts/ aquí puedes poner  Charts que son dependencias de tu Chart principal, por ejemplo puedes hacer un chart que se llame "monitoreo" y que depende charts como "grafana", "prometheus", "thanos", etc.
 - templates/ aquí están las plantillas de kubernetes, aquí están las plantillas de los recursos de kubernetes, despliegues (deployments), servicios (services), configuraciones (configmaps), secretos (secrets), ingress, etc.
 - templates/_helpers.tpl básicamente, estos archivos pueden incluir bucles, condicionales, y funciones para generar configuraciones dinámicas.
 - templates/Notes.txt contiene las instrucciones o información que se mostrará después de instalar  el Chart.


Vamos dentro de templates/ y para este caso eliminaré los archivos: hpa.yaml, ingress.yaml, serviceaccount.yaml, y el directorio test/test-connection.yaml.

Ahora modificamos el archivo deployment.yaml

**Nota:** En mi caso me gusta tener todo ordenado por lo que primero creo un template llamado namespace con el siguiente contenido:


	---
    apiVersion: v1
    kind: Namespace
    metadata:
      name: {{ .Values.namespace }}
	---  


Ahora vamos a ver el deployment.yaml:

    ---
    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: {{ include "nginx-chart.fullname" . }}
      namespace: {{ .Values.namespace }}
    spec:
      replicas: {{ .Values.replicaCount }}
      selector:
        matchLabels:
          app: {{- include "nginx-chart.selectorLabels" . | nindent 6 }}
      template:
        metadata:
          labels:
            app: {{- include "nginx-chart.selectorLabels" . | nindent 8 }}
        spec:
          containers:
          - name: nginx
            image: {{ .Values.image.repository }}:{{ .Values.image.tag }}
            ports:
            - containerPort: 80
    ---        

Ahora nuestro templates/service.yaml:

    ---
    apiVersion: v1
    kind: Service
    metadata:
      name: {{ include "nginx-chart.fullname" . }}
      namespace: {{ .Values.namespace }}
    spec:
      selector:
        app: {{- include "nginx-chart.labels" . | nindent 4 }}
      ports:
        - protocol: TCP
          port: {{ .Values.service.port }}
          targetPort: 80
    ---

Esto es **opcional**, ya que yo tengo metallb en mi laboratorio local:

    ---
    apiVersion: v1
    kind: Service
    metadata:
      name: loadbalancer-{{ include "nginx-chart.fullname" . }}
      namespace: {{ .Values.namespace }}
    spec:
      ports:
        - port: 80
          targetPort: {{ .Values.service.port }}
          protocol: TCP
      type: LoadBalancer
      selector:
        app: {{- include "nginx-chart.selectorLabels" . | nindent 4 }}
    ---

Si no tienes instalado metallb, lo que debes hacer es un port-forward del service, despues que instalemos el paquete.

En nuestro values.yaml buscamos y editamos los valores que queramos para la cantidad de replicas y el puerto por el cual accederemos al servicio.

    ---
    namespace: nginx-chart
    replicaCount: 2
    image:
      repository: nginx
      tag: latest
    service:
      port: 8080
    ---

**Nota:** Podemos borrar el resto de parámetros si queremos para que nos hagan "ruido" en nuestra configuración.

Vamos a poner un mensaje cuando se instala el paquete, para eso vamos a editar nuestro templates/NOTES.txt

```
Nginx se ha desplegado correctamente. Puedes acceder a la aplicación a través de http://{{ .Release.Name }}.{{ .Values.service.port }}
```

En nuestro Chart.yaml, vamos a poner los metadatos siguientes:


    ---
    apiVersion: v2
    name: nginx-chart
    description: A Helm chart for deploying Nginx
    version: "1.0.0"
    ---

**Nota:** En mi caso yo inicié con la versión 1.0.0, por default si inicia con 0.1.0.

## Linter, errores a la vista!

Ya que hemos realizado los cambios que queremos en nuestro paquete, podemos ejecutar el linter para comprobar que no hay errores, typos, etc. Esto lo hacemos desde el folder donde están los archivos Chart.yaml y values.yaml.

```bash
helm lint
```

## Empaquetado

Ya que hemos realizado los pasos anteriores, vamos a empaquetar nuestro Chart.

```bash
helm package nginx-chart
```

Estos te creará un tarball de nuestro paquete.

Antes de instalarlo podemos hacer un "fake install" del paquete para ver la salida con las sustituciones que hará en los manifest.

```bash
helm install nginx-chart nginx-chart-1.0.0.tgz --dry-run --debug
```

Si todo está bien, para instalarlo solo debes hacer:

```bash
helm install nombre-del-release nginx-chart-1.0.0.tgz -n namespace

helm install my-nginx my-nginx-1.0.0.tgz --namespace nginx-chart
```

**Nota:** el paráemtro -n nombre_del_namespace es opcional, en caso que no hayas creado un archivo namespace.yaml.

Y obtendrás una salida como esta:

Obviamente podemos usar kubectl para comprobar que todo lo que dice el Chart se ha aplicado correctamente, y si abrimos el navegador y ponemos la EXTERNAL-IP:


## Helm administrando paquetes

Dado que helm es un manejador de paquetes, podemos listar, actualizar y borrar paquetes, como si se tratase de apt, pacman, pip, etc.


```bash
helm list --all-namespaces
```
Es importante el --all-namespaces de lo contrario solo te mostrará lo que esta en el namespace default.

Para actualizar en caso que tengamos una nueva versión del paquete.

```bash
helm update nginx-chart
```

## Historial de revisiones y rollback

Para ver el historial de revisiones:

```bash
helm history nginx-chart
```
Por ejemplo para hacer un rollback a la revisión 1:

```bash
helm rollback nginx-chart 1
```

es decir, que si quieres ir a la revisión 4 debes cambiar el valor de 1 a 4.

Hasta aquí lo dejamos por ahora, en el siguiente post te enseño cómo hacer tu propio repositorio de paquetes.

No hay comentarios.: