Desbloqueando la Flexibilidad y Reutilización: Aprovechando el Poder de los Subgráficos de Múltiples Instancias de Helm

Desbloqueando la Flexibilidad y Reutilización: Aprovechando el Poder de los Subgráficos de Múltiples Instancias de Helm

El uso de subgráficos de múltiples instancias de Helm como parte de tu gráfico principal podría ser algo que, desde el principio, puede sonar extraño. Ya comentamos sobre los subgráficos y dependencias de los gráficos de helm en el blog porque el caso de uso habitual es así:

Tengo un gráfico que necesita otro componente, y lo «importo» como un subgráfico, lo que me da la posibilidad de desplegar el mismo componente y personalizar sus valores sin necesidad de crear otra copia del gráfico y, como puedes imaginar, simplificando mucho la gestión de los gráficos, un ejemplo puede ser así:

Descubre cómo múltiples subgráficos pueden revolucionar tus despliegues de Helm. Aprende a aprovechar el poder de la reutilización y personalización, permitiéndote desplegar componentes idénticos con configuraciones únicas. Mejora la flexibilidad y simplifica la gestión con esta avanzada característica de Helm. Desbloquea todo el potencial de tu arquitectura de microservicios y toma el control de despliegues de aplicaciones complejas. Sumérgete en el mundo de múltiples subgráficos y eleva tus gráficos de Helm al siguiente nivel.

Entonces, creo que eso está totalmente claro, pero ¿de qué estamos hablando ahora? El caso de uso es tener el mismo subgráfico definido dos veces. Así que, imagina este escenario, estamos hablando de eso en lugar de esto:

# Chart.yaml
dependencies:
- name: nginx
  version: "1.2.3"
  repository: "https://example.com/charts"
- name: memcached
  version: "3.2.1"
  repository: "https://another.example.com/charts"

Estamos teniendo algo como esto

# Chart.yaml
dependencies:
- name: nginx
  version: "1.2.3"
  repository: "https://example.com/charts"
- name: memcached-copy1
  version: "3.2.1"
  repository: "https://another.example.com/charts"
- name: memcached-copy2
  version: "3.2.1"
  repository: "https://another.example.com/charts"

Así que tenemos la opción de definir más de una «instancia» del mismo subgráfico. Y supongo que, en este momento, puedes empezar a preguntarte: «¿Cuáles son los casos de uso donde podría necesitar esto?»

Porque eso es bastante comprensible, a menos que lo necesites nunca te darás cuenta de eso. Es lo mismo que me pasa a mí. Así que hablemos un poco sobre posibles casos de uso para esto.

 Casos de Uso para Dependencia de Múltiples Instancias de Helm

Imagina que estás desplegando un gráfico de helm para un conjunto de microservicios que pertenecen al ámbito de la misma aplicación y cada uno de los microservicios tiene la misma base tecnológica, que puede ser TIBCO BusinessWorks Container Edition o pueden ser microservicios Golang. Así que todos ellos tienen la misma base por lo que pueden usar el mismo gráfico «bwce-microservice» o «golang-microservices» pero cada uno de ellos tiene su propia configuración, por ejemplo:

  • Cada uno de ellos tendrá su propio nombre de imagen que diferirá de uno a otro.
  • Cada uno de ellos tendrá su propia configuración que diferirá de uno a otro.
  • Cada uno de ellos tendrá sus propios puntos de conexión que diferirán y probablemente incluso se conectarán a diferentes fuentes como bases de datos o sistemas externos.

Así que, este enfoque nos ayudaría a reutilizar el mismo gráfico de helm tecnológico, «bwce» e instanciarlo varias veces, para que podamos tener cada uno de ellos con su propia configuración sin la necesidad de crear algo «personalizado» y manteniendo los mismos beneficios en términos de mantenibilidad que el enfoque de dependencia de helm nos proporciona.

 ¿Cómo podemos implementar esto?

Ahora que tenemos claro el caso de uso que vamos a soportar, el siguiente paso es sobre cómo podemos hacer esto una realidad. Y, para ser honesto, esto es mucho más simple de lo que puedes pensar desde el principio, comencemos con la situación normal cuando tenemos un gráfico principal, llamémoslo un «programa», que ha incluido una plantilla «bwce» como una dependencia como puedes ver aquí:

name: multi-bwce
description: Helm Chart para Desplegar una Aplicación TIBCO BusinessWorks Container Edition
apiVersion: v1
version: 0.2.0
icon: 
appVersion: 2.7.2

dependencies:
- name: bwce
  version: ~1.0.0
  repository: "file:///Users/avazquez/Data/Projects/DET/helm-charts/bwce"

Y ahora, vamos a movernos a un enfoque de múltiples instancias donde requeriremos dos microservicios diferentes, llamémoslos serviceA y serviceB, y ambos usarán el mismo gráfico de helm bwce.

Así que lo primero que modificaremos es el Chart.yaml de la siguiente manera:

name: multi-bwce
description: Helm Chart para Desplegar una Aplicación TIBCO BusinessWorks Container Edition
apiVersion: v1
version: 0.2.0
icon: 
appVersion: 2.7.2

dependencies:
- name: bwce
  alias: serviceA
  version: ~0.2.0
  repository: "file:///Users/avazquez/Data/Projects/DET/helm-charts/bwce"
- name: bwce
  alias: serviceB
  version: ~0.2.0
  repository: "file:///Users/avazquez/Data/Projects/DET/helm-charts/bwce"

La parte importante aquí es cómo declaramos la dependencia. Como puedes ver en el nombre seguimos manteniendo el mismo «nombre» pero tienen un campo adicional llamado «alias» y este alias es lo que nos ayudará a identificar más tarde las propiedades para cada una de las instancias según lo requiramos. Con eso, ya tenemos nuestra definición de instancia de serviceA y serviceB y podemos comenzar a usarlo en el values.yml de la siguiente manera:

# Este es un archivo con formato YAML.
# Declara variables para ser pasadas a tus plantillas.

serviceA:
  image: 
    imageName: 552846087011.dkr.ecr.eu-west-2.amazonaws.com/tibco/serviceA:2.5.2
    pullPolicy: Always
serviceB:  
  image: 
    imageName: 552846087011.dkr.ecr.eu-west-2.amazonaws.com/tibco/serviceB:2.5.2
    pullPolicy: Always
  

 Conclusión

El principal beneficio de esto es que mejora las opciones de usar gráficos de helm para aplicaciones «complejas» que requieren diferentes instancias del mismo tipo de componentes y al mismo tiempo.

Eso no significa que necesites un gráfico de helm enorme para tu proyecto porque esto iría en contra de todas las mejores prácticas del enfoque de contenedorización y microservicios, pero al menos te dará la opción de definir diferentes niveles de abstracción como desees, manteniendo todos los beneficios desde una perspectiva de gestión.

Dependencia de Helm: Descubre Cómo Funciona

Dependencia de Helm: Descubre Cómo Funciona

La Dependencia de Helm es una parte crítica para entender cómo funciona Helm, ya que es la forma de establecer relaciones entre diferentes paquetes de helm. Hemos hablado mucho aquí sobre qué es Helm, y algunos temas relacionados, e incluso proporcionamos algunos trucos si creas tus gráficos.

Entonces, como se comentó, Helm Chart no es más que un paquete que colocas alrededor de los diferentes objetos de Kubernetes que necesitan ser desplegados para que tu aplicación funcione. La comparación habitual es que es similar a un Paquete de Software. Cuando instalas una aplicación que depende de varios componentes, todos esos componentes se empaquetan juntos, y aquí es lo mismo.

¿Qué es una Dependencia de Helm?

Una Dependencia de Helm no es más que la forma en que defines que tu Chart necesita otro chart para funcionar. Por supuesto, puedes crear un Helm Chart con todo lo que necesitas para desplegar tu aplicación, pero a veces te gustaría dividir ese trabajo en varios charts simplemente porque son fáciles de mantener o el caso de uso más común porque quieres aprovechar otro Helm Chart que ya está disponible.

Un caso de uso puede ser una aplicación web que requiere una base de datos, por lo que puedes crear en tu Helm Chart todos los archivos YAML para desplegar tu aplicación web y tu base de datos en Kubernetes, o puedes tener tus archivos YAML para tu aplicación web (Deployment, Services, ConfigMaps,…) y luego decir: Y necesito una base de datos y para proporcionarla voy a usar este chart.

Esto es similar a cómo funciona con los paquetes de software en sistemas UNIX; tienes tu paquete que hace el trabajo, como, por ejemplo, A, pero para que ese trabajo se realice, requiere la biblioteca L, y para asegurar que cuando estás instalando A, la Biblioteca L ya esté allí o si no, se instalará, declaras que tu aplicación A depende de la Biblioteca L, así que aquí es lo mismo. Declaras que tu Chart depende de otro Chart para funcionar. Y eso nos lleva al siguiente punto.

¿Cómo declaramos una Dependencia de Helm?

Este es el siguiente punto; ahora que entendemos qué es una Dependencia de Helm conceptualmente y tenemos un caso de uso, ¿cómo podemos hacer eso en nuestro Helm Chart?

Todo el trabajo se realiza en el archivo Chart.yml. Si recuerdas, el archivo Chart.yml es el archivo donde declaras todos los metadatos de tu Helm Chart, como el nombre, la versión del chart, la versión de la aplicación, la URL de ubicación, el icono y mucho más. Y generalmente tiene una estructura como esta:

apiVersion: v2
name: MyChart
description: My Chart Description
type: application
version: 0.2.0
appVersion: "1.16.0"

Así que aquí podemos agregar una sección dependencies y, en esa sección es donde vamos a definir los charts de los que dependemos. Como puedes ver en el fragmento a continuación:

apiVersion: v2
name: MyChart
description: My Chart Description
type: application
version: 0.2.0
appVersion: "1.16.0"
dependencies:
- name: Dependency
  version: 1.0.0
  repository: "file:///location_of_my_chart"

Aquí estamos declarando Dependency como nuestra Dependencia de Helm. Especificamos la versión que nos gustaría usar (similar a la versión que decimos en nuestro chart), y eso nos ayudará a asegurar que proporcionaremos la misma versión que ha sido probada como parte de la resolución de la dependencia y también la ubicación usando una URL que puede ser una URL externa si esto está apuntando a un Helm Chart que está disponible en internet o fuera de tu computadora o usando una Ruta de Archivo en caso de que estés apuntando a un recurso local en tu máquina.

Eso hará el trabajo de definir la dependencia de helm, y de esta manera, cuando instales tu chart usando el comando helm install, también proporcionará la dependencia.

¿Cómo declaro una Dependencia Condicional de Helm?

Hasta ahora, hemos aprendido cómo declarar una dependencia, y cada vez que aprovisiono mi aplicación, también proporcionará la dependencia. Pero generalmente nos gustaría tener un enfoque más detallado para eso. Imagina el mismo escenario anterior: Tenemos nuestra Aplicación Web que depende de la Base de Datos, y tenemos dos opciones, podemos aprovisionar la base de datos como parte de la instalación de la aplicación web, o podemos apuntar a una base de datos externa y en ese caso, no tiene sentido aprovisionar la Dependencia de Helm. ¿Cómo podemos hacer eso?

Entonces, fácil, porque uno de los parámetros opcionales que puedes agregar a tu dependencia es condition y hacer exactamente eso, condition te permite especificar una bandera en tu values.yml que en el caso sea igual a true, proporcionará la dependencia pero en el caso sea igual a false omitirá esa parte similar al fragmento mostrado a continuación:

 apiVersion: v2
name: MyChart
description: My Chart Description
type: application
version: 0.2.0
appVersion: "1.16.0"
dependencies:
- name: Dependency
  version: 1.0.0
  repository: "file:///location_of_my_chart"
  condition: database.enabled 

Y con eso, estableceremos el parámetro enabled bajo database en nuestro values.yml a true si nos gustaría aprovisionarlo.

¿Cómo declaro una Dependencia de Helm con una versión diferente?

Como se muestra en los fragmentos anteriores, ofrecemos que cuando declaramos una Dependencia de Helm, especificamos la versión; esa es una forma segura de hacerlo porque asegura que cualquier cambio realizado en el chart de helm no afectará tu paquete. Sin embargo, al mismo tiempo, no puedes estar al tanto de correcciones de seguridad o parches en el chart que te gustaría aprovechar en tu implementación.

Para simplificar eso, tienes la opción de definir la versión de una manera más flexible usando el operador ~ en la definición de la versión, como puedes ver en el fragmento a continuación:

apiVersion: v2
name: MyChart
description: My Chart Description
type: application
version: 0.2.0
appVersion: "1.16.0"
dependencies:
- name: Dependency
  version: ~1.0.0
  repository: "file:///location_of_my_chart"
  condition: database.enabled 

Esto significa que cualquier parche realizado en el chart será aceptado, por lo que esto es similar a que este chart usará la última versión de 1.0.X. Sin embargo, no usará la versión 1.1.0, por lo que eso permite tener más flexibilidad, pero al mismo tiempo mantener las cosas seguras y protegidas en caso de un cambio importante en el Chart del que dependes. Esta es solo una forma de definir eso, pero la flexibilidad es enorme ya que las versiones de Chart usan «Versiones Semánticas», Puedes aprender y leer más sobre eso aquí: https://github.com/Masterminds/semver.