Administración de una versión de Helm

Completado

Uso de funciones en una plantilla de Helm

El lenguaje de plantillas de Helm define funciones que se usan para transformar valores del archivo values.yaml. La sintaxis de una función sigue la estructura {{functionName arg1 arg2 ...}}. Echemos un vistazo a la función quote como ejemplo para ver el uso de esta sintaxis.

La función quote encapsula un valor entre comillas para indicar el uso de string. Supongamos que define el siguiente archivo values.yaml:

apiVersion: v2
name: webapp
description: A Helm chart for Kubernetes
ingress:
  enabled: true

Decide usar el valor ingress.enabled como booleano al determinar si se debe generar un manifiesto de entrada. Para usar el valor enabled como booleano, hace referencia al valor mediante {{ .Values.ingress.enabled }}.

Más adelante, decide mostrar el campo como una cadena en el archivo templates/Notes.txt. Dado que las reglas de coerción de tipos de YAML pueden dar lugar a errores difíciles de encontrar en las plantillas, decide seguir las instrucciones y ser explícito al incluir cadenas en las plantillas. Por ejemplo, enabled: false no es igual que enabled: "false".

Para mostrar el valor como una cadena, utiliza {{ quote .Values.ingress.enabled }} para hacer referencia al valor booleano como una cadena.

Uso de canalizaciones en una plantilla de Helm

Utilice canalizaciones cuando sea necesario que más de una función actúen en un valor. Una canalización le permite enviar un valor o el resultado de una función a otra función. Por ejemplo, puede reescribir la función quote anterior como {{ .Values.ingress.enabled | quote }}. Observe cómo | indica que el valor se envía a la función quote.

Este es otro ejemplo. Supongamos que quiere convertir un valor en mayúsculas y encapsularlo entre comillas. Puede escribir la instrucción como {{ .Values.ingress.enabled | upper | quote }}. Fíjese en cómo el valor lo procesa la función upper y, a continuación, la función quote.

El lenguaje de plantillas incluye más de 60 funciones que permiten exponer, buscar y transformar valores y objetos de las plantillas.

Procedimiento para usar el control de flujo condicional en una plantilla de Helm

El control de flujo condicional le permite decidir la estructura o los datos que se incluyen en el archivo de manifiesto generado. Por ejemplo, puede que quiera incluir valores diferentes según el destino o el control de implementación si se genera un archivo de manifiesto.

El bloque if / else es una estructura de flujo de control de este tipo y se ajusta al siguiente diseño:

{{ if | pipeline | }}
  # Do something
{{ else if | other pipeline | }}
  # Do something else
{{ else }}
  # Default case
{{ end }}

Supongamos que decide que el archivo de manifiesto de entrada de un gráfico solo se cree en casos concretos. El siguiente ejemplo muestra cómo lograrlo usando una instrucción if:

{{ if .Values.ingress.enabled }}
apiVersion: extensions/v1
kind: Ingress
metadata:
  name: ...
  labels:
    ...
  annotations:
    ...
spec:
  rules:
    ...
{{ end }}

Recuerde que puede usar marcadores de posición para rellenar los metadatos de la plantilla. El lenguaje de plantilla analiza y evalúa secuencialmente los archivos de plantilla de arriba abajo. En el ejemplo anterior, el motor de plantillas solo genera el contenido del archivo de manifiesto si el valor .Values.ingress.enabled es true.

Cuando el motor de plantillas procesa la instrucción, quita el contenido declarado dentro de la sintaxis {{ }} y deja el espacio en blanco que queda. Esta sintaxis hace que el motor de plantillas incluya una línea nueva para la línea de la instrucción if. Si deja tal cual el contenido del archivo anterior, observará líneas vacías en el código YAML y se generará el archivo de manifiesto de entrada.

YAML da significado al espacio en blanco. Por eso se consideran importantes las tabulaciones, los espacios y los caracteres de nueva línea. Para solucionar el problema de un espacio en blanco no deseado, puede reescribir el archivo de la manera siguiente:

{{- if .Values.ingress.enabled -}}
apiVersion: extensions/v1
kind: Ingress
metadata:
  name: ...
  labels:
    ...
  annotations:
    ...
spec:
  rules:
    ...
{{- end }}

Fíjese en el uso del carácter - como parte de la secuencia {{- inicial y la secuencia -}} final de la instrucción. El carácter - indica al analizador que quite los caracteres de espacio en blanco. {{- quita el espacio en blanco al principio de una línea y -}} al final de una línea, incluido el carácter de nueva línea.

Procedimiento para iterar por una colección de valores de una plantilla de Helm

YAML le permite definir colecciones de elementos y usar elementos individuales como valores en las plantillas. Se puede acceder a los elementos de una colección mediante un indexador. Sin embargo, el lenguaje de plantilla de Helm admite la iteración de una colección de valores mediante el operador range.

Supongamos que define una lista de valores en el archivo values.yaml para indicar hosts de entrada adicionales. Este es un ejemplo de los valores:

ingress:
  enabled: true
  extraHosts:
    - name: host1.local
      path: /
    - name: host2.local
      path: /
    - name: host3.local
      path: /

El operador de rango se usa para permitir que el motor de plantillas itere por .Values.ingress.extraHosts. El siguiente fragmento de código muestra un ejemplo condensado usando el operador range:

{{- if .Values.ingress.enabled -}}
apiVersion: extensions/v1
kind: Ingress
metadata:
  ...
spec:
  rules:
    ...
    {{- range .Values.ingress.extraHosts }}
    - host: {{ .name }}
      http:
        paths:
          - path: {{ .path }}
            ...
    {{- end }}
  ...
{{- end }}

Procedimiento para controlar el ámbito de los valores de una plantilla de Helm

Si tiene valores definidos en varias capas, la sintaxis puede ser larga y tediosa al incluir estos valores en una plantilla. La acción with le permite limitar el ámbito de las variables de una plantilla.

Recuerde que el elemento . utilizado en una plantilla de Helm hace referencia al ámbito actual. Por ejemplo, .Values indica al motor de plantillas que busque el objeto Valores en el ámbito actual. Supongamos que está usando el archivo values.yaml anterior para crear un archivo de manifiesto de asignación de configuración:

ingress:
  enabled: true
  extraHosts:
    - name: host1.local
      path: /
    - name: host2.local
      path: /
    - name: host3.local
      path: /

En lugar de acceder al valor de ruta de acceso de cada elemento mediante {{ .Values.ingress.extraHosts.path }}, puede usar la acción with. El siguiente fragmento de código muestra un ejemplo de uso del operador range para generar un archivo de manifiesto de asignación de configuración:

apiVersion: v1
kind: ConfigMap
metadata:
  name: {{ .Release.Name }}-configmap
data:
  {{- with .Values.ingress.extraHosts }}
  hostname: {{ .name }}
  path: {{ .path }}
  {{ end }}

{{- with .Values.ingress.extraHosts }} limita el ámbito de los valores a la matriz .Values.ingress.extraHosts.

La acción with restringe el ámbito. No se puede acceder a otros objetos del ámbito primario. Supongamos que también quiere acceder al elemento {{ .Release.Name }} del gráfico en el bloque de código with. Para acceder a los objetos primarios, debe indicar el ámbito raíz mediante el carácter $ o reescribir el código. Este es el código actualizado para mostrar cómo se incluyen los objetos primarios mediante el carácter $:

apiVersion: v1
kind: ConfigMap
metadata:
  name: {{ .Release.Name }}-configmap
data:
  {{- with .Values.ingress.extraHosts }}
  hostname: {{ .name }}
  path: {{ .path }}
  release: {{ $.Release.Name}}
  {{ end }}

Nota:

Hay varias construcciones disponibles en el lenguaje de plantilla de Helm para el flujo de control. La unidad de resumen de este módulo incluye una sección con vínculos a la documentación de Helm para obtener más información.

Cómo definir dependencias de gráficos de Helm

Un gráfico permite que la declaración de dependencias admita la aplicación principal y forma parte de la versión instalada.

A diagram shows how Helm deploys all subcharts as dependencies of the main chart to a Kubernetes cluster.

Puede crear un subgráfico mediante el comando helm create, especificando la ubicación del nuevo gráfico en la carpeta /charts o usando el comando helm dependency. Recuerde que la carpeta /charts puede contener subgráficos implementados como parte de la versión del gráfico principal.

El comando helm dependency le permite administrar las dependencias que se incluyen en un repositorio de Helm. El comando usa los metadatos definidos en la sección dependencies del archivo de valores del gráfico. Debe especificar el nombre, el número de versión y el repositorio desde el que se va a instalar el subgráfico. Este es un extracto de un archivo values.yaml con un gráfico de MongoDB que se muestra como una dependencia:

apiVersion: v2
name: my-app
description: A Helm chart for Kubernetes
...
dependencies:
  - name: mongodb
    version: 10.27.2
    repository: https://marketplace.azurecr.io/helm/v1/repo

Una vez definidos los metadatos de dependencia, ejecute el comando helm dependency build para capturar el gráfico empaquetado de .tar. El comando de compilación del gráfico descarga el gráfico en la carpeta charts/.

helm dependency build ./app-chart

Los subgráficos se administran de forma independiente del gráfico principal y es posible que necesiten actualizaciones a medida que estén disponibles nuevas versiones. El comando para actualizar los subgráficos es helm dependency update. Este comando recupera las nuevas versiones del subgráfico y elimina los paquetes obsoletos.

helm dependency update ./app-chart

Tenga en cuenta que la dependencia de un gráfico no se limita a otras aplicaciones. Puede decidir reutilizar la lógica de plantilla en los gráficos y crear una dependencia específicamente para administrar esta lógica como una dependencia de gráfico. En el siguiente ejercicio verá un ejemplo de esta estrategia.

Procedimiento para actualizar una versión de Helm

Helm permite actualizar las versiones existentes como un elemento delta de todos los cambios que se aplican al gráfico y a sus dependencias.

A diagram shows how the Helm upgrade command creates a delta of all changed items in a Helm chart to upgrade a release and create a new release revision on a Kubernetes cluster.

Por ejemplo, supongamos que el equipo de desarrollo del ejemplo webapp de esta unidad realiza cambios en el código que afectan solo a las funciones del sitio web. El equipo realiza las siguientes actualizaciones en el archivo Chart.yaml para reflejar la nueva versión de la aplicación:

  • Actualiza la imagen de contenedor de la aplicación web y etiqueta la imagen como webapp: linux-v2 al insertarla en el registro de contenedor.
  • Actualiza el valor dockerTag a linux-v2 y el valor de la versión del gráfico a 0.2.0 en el archivo de valores del gráfico.

Este es un ejemplo del archivo values.yaml actualizado:

apiVersion: v2
name: my-app
description: A Helm chart for Kubernetes

type: application

version: 0.2.0
appVersion: 1.0.0

registry: "my-acr-registry.azurecr.io"
dockerTag: "linux-v2"
pullPolicy: "Always"

En lugar de desinstalar la versión actual, use el comando helm upgrade para actualizar la versión existente de Helm.

helm upgrade my-app ./app-chart

Recuerde que Helm genera un elemento delta de los cambios realizados en el gráfico de Helm al actualizar una versión. Como tal, una actualización de Helm solo actualiza los componentes identificados en el elemento delta. En el ejemplo, solo se vuelve a implementar el sitio web.

Una vez finalizada la actualización, puede revisar el historial de implementación de la versión usando el comando helm history con el nombre de la versión.

helm history my-app

El comando de historial devuelve varios campos que describen la versión, como se muestra en el siguiente ejemplo de salida:

REVISION        UPDATED                         STATUS          CHART                   APP VERSION     DESCRIPTION
1               Mon Oct 11 17:25:33 2021        deployed        aspnet-core-1.3.18      3.1.19          Install complete

Fíjese en el campo revision del resultado. Helm realiza un seguimiento de la información de todas las versiones generadas para un gráfico de Helm. Al instalar una nueva versión de un gráfico de Helm, el número de revisiones aumenta en uno, y la información de la nueva versión se asocia a esa revisión.

Este es un ejemplo de ejecución del mismo comando de historial, después de instalar una nueva versión de la aplicación web:

REVISION        UPDATED                         STATUS          CHART                   APP VERSION     DESCRIPTION
1               Mon Oct 11 17:25:33 2021        superseded      aspnet-core-1.3.18      3.1.19          Install complete
2               Mon Oct 11 17:35:13 2021        deployed        aspnet-core-1.3.18      3.1.19          Upgrade complete

Procedimiento para revertir una versión de Helm

Helm permite la reversión de una versión existente de Helm a una versión instalada previamente. Recuerde que Helm realiza un seguimiento de la información de todas las versiones de un gráfico de Helm.

Use el comando helm rollback para revertir a una revisión de versión de Helm concreta. Este comando utiliza dos parámetros. El primer parámetro identifica el nombre de la versión, y el segundo, el número de revisión de la versión.

helm rollback my-app 2

El comando helm rollback revertirá la versión de la aplicación a la revisión especificada y actualizará el historial de versiones de la aplicación. Una nueva ejecución del comando helm history mostrará el número de revisión activo más reciente como última entrada de la versión.

Por ejemplo, supongamos que el equipo de desarrollo del ejemplo webapp de esta unidad descubre un error en la aplicación web de seguimiento de drones y necesita volver a una versión anterior. En lugar de desinstalar la versión actual e instalar una versión anterior, vuelven a la versión que funcionaba.

helm rollback my-app 1

Una vez finalizada una reversión, puede revisar el historial de implementación con el comando helm history.

REVISION        UPDATED                         STATUS          CHART                   APP VERSION     DESCRIPTION
1               Mon Oct 11 17:25:33 2021        superseded      aspnet-core-1.3.18      3.1.19          Install complete
2               Mon Oct 11 17:35:13 2021        superseded      aspnet-core-1.3.18      3.1.19          Rolled back to 1
3               Mon Oct 11 17:38:13 2021        deployed        aspnet-core-1.3.18      3.1.19          Upgrade complete

Fíjese en cómo el campo de la descripción muestra el número de revisión de la reversión para facilitar el seguimiento de los cambios.

Comprobación de conocimientos

1.

Supongamos que tiene una solución de software con dos componentes críticos: una aplicación web y un servicio que procesa los pedidos en línea. Los dos componentes forman parte de una canalización de procesamiento de pedidos en línea, pero no son dependientes entre sí. ¿Qué estrategia sería la más adecuada para implementar estas dos aplicaciones con Helm?

2.

Digamos que tiene una solución de software que tiene un sitio web como uno de sus componentes críticos. El sitio web es el único componente que depende de un servicio de almacenamiento en caché. ¿Qué estrategia sería la más adecuada para implementar estas dos aplicaciones con Helm?