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.

Dockerfile de Múltiples Etapas: Enfoque Asombroso para Optimizar el Tamaño de tu Contenedor

Dockerfile de Múltiples Etapas: Enfoque Asombroso para Optimizar el Tamaño de tu Contenedor

El Dockerfile de múltiples etapas es el patrón que puedes usar para asegurar que tu imagen de Docker esté en un tamaño optimizado. Ya hemos cubierto la importancia de mantener el tamaño de tu imagen de Docker al mínimo y qué herramientas podrías usar, como dive, para entender el tamaño de cada una de tus capas. Pero hoy, vamos a seguir un enfoque diferente y ese enfoque es una construcción de múltiples etapas para nuestros contenedores Docker.

¿Qué es un patrón de Dockerfile de múltiples etapas?

El Dockerfile de múltiples etapas se basa en el principio de que el mismo Dockerfile puede tener diferentes sentencias FROM y cada una de las sentencias FROM inicia una nueva etapa de la construcción.

Patrón de Dockerfile de múltiples etapas

¿Por qué el patrón de construcción de múltiples etapas ayuda a reducir el tamaño de las imágenes de contenedores?

La razón principal por la que el uso de patrones de construcción de múltiples etapas ayuda a reducir el tamaño de los contenedores es que puedes copiar cualquier artefacto o conjunto de artefactos de una etapa a otra. Y esa es la razón más importante. ¿Por qué? Porque eso significa que todo lo que no copias es descartado y no estás llevando todos estos componentes no requeridos de capa en capa, generando un tamaño innecesario mayor de la imagen final de Docker.

¿Cómo defines un Dockerfile de múltiples etapas?

Primero, necesitas tener un Dockerfile con más de un FROM. Como se comentó, cada uno de los FROM indicará el inicio de una etapa del Dockerfile de múltiples etapas. Para diferenciarlos o referenciarlos, puedes nombrar cada una de las etapas del Dockerfile usando la cláusula AS junto al comando FROM, como se muestra a continuación:

 FROM eclipse-temurin:11-jre-alpine AS builder

Como una buena práctica, también puedes agregar una nueva etiqueta de etapa con el mismo nombre que proporcionaste antes, pero eso no es necesario. Así que, en resumen, un Dockerfile de múltiples etapas será algo como esto:

FROM eclipse-temurin:11-jre-alpine AS builder
LABEL stage=builder
COPY . /
RUN apk add  --no-cache unzip zip && zip -qq -d /resources/bwce-runtime/bwce-runtime-2.7.2.zip "tibco.home/tibcojre64/*"
RUN unzip -qq /resources/bwce-runtime/bwce*.zip -d /tmp && rm -rf /resources/bwce-runtime/bwce*.zip 2> /dev/null


FROM  eclipse-temurin:11-jre-alpine 
RUN addgroup -S bwcegroup && adduser -S bwce -G bwcegroup

¿Cómo copias recursos de una etapa a otra?

Esta es la otra parte importante aquí. Una vez que hemos definido todas las etapas que necesitamos, y cada una está haciendo su parte del trabajo, necesitamos mover datos de una etapa a la siguiente. Entonces, ¿cómo podemos hacer eso?

La respuesta es usando el comando COPY. COPY es el mismo comando que usas para mover datos desde tu almacenamiento local a la imagen del contenedor, por lo que necesitarás una forma de diferenciar que esta vez no lo estás copiando desde tu almacenamiento local sino desde otra etapa, y aquí es donde vamos a usar el argumento --from. El valor será el nombre de la etapa que aprendimos a declarar en la sección anterior. Así que un comando COPY completo será algo como el fragmento mostrado a continuación:

 COPY --from=builder /resources/ /resources/

¿Cuál es la mejora que puedes obtener?

Esa es la parte esencial y dependerá de cómo se crean tus Dockerfiles e imágenes, pero el factor principal que puedes considerar es el número de capas que tiene tu imagen actual. Cuanto mayor sea el número de capas, más significativo será el ahorro que probablemente puedas lograr en la cantidad de la imagen final del contenedor en un Dockerfile de múltiples etapas.

La razón principal es que cada capa duplicará parte de los datos, y estoy seguro de que no necesitarás todos los datos de la capa en la siguiente. Y usando el enfoque comentado en este artículo, obtendrás una forma de optimizarlo.

 ¿Dónde puedo leer más sobre esto?

Si quieres leer más, debes saber que el Dockerfile de múltiples etapas está documentado como una de las mejores prácticas en la página web oficial de Docker, y tienen un gran artículo sobre esto por Alex Ellis que puedes leer aquí.

📚 Want to dive deeper into Kubernetes? This article is part of our comprehensive Kubernetes Architecture Patterns guide, where you’ll find all fundamental and advanced concepts explained step by step.

Cómo inyectar secretos en pods para mejorar la seguridad con Hashicorp Vault en 5 minutos

Cómo inyectar secretos en pods para mejorar la seguridad con Hashicorp Vault en 5 minutos

Introducción

Este artículo cubrirá cómo inyectar secretos en Pods usando Hashicorp Vault. En artículos anteriores, cubrimos cómo instalar Hashicorp Vault en Kubernetes, configurar y crear secretos en Hashicorp, y cómo herramientas como TIBCO BW pueden recuperarlos. Sin embargo, hoy vamos a dar un paso más allá.

La razón por la cual inyectar secretos en pods es muy importante es que permite que la aplicación dentro del pod sea transparente en torno a cualquier comunicación con Hashicorp. Después de todo, para las aplicaciones, el secreto será solo un archivo regular ubicado en una ruta específica dentro del contenedor. No necesita preocuparse si este archivo proviene de un Secreto de Hashicorp o de un recurso totalmente diferente.

Este enfoque de inyección facilita el enfoque poliglota del ecosistema de Kubernetes porque libera cualquier responsabilidad de la aplicación subyacente. Lo mismo ocurre con enfoques de inyección como Istio o mucho más.

Pero, expliquemos cómo funciona este enfoque para inyectar secretos en Pods usando Hashicorp Vault. Como parte de la instalación junto al servidor de vault que hemos instalado (o varios si has hecho una instalación distribuida), hemos visto otro pod bajo el nombre de value-agent-injector, como puedes ver en la imagen a continuación:

Inyectar Secretos en Pods: Pod del Inyector de Vault

Este agente será responsable de escuchar los nuevos despliegues que realices y, basado en las anotaciones que tenga este despliegue, lanzará un sidecar junto a tu aplicación y enviará la configuración para poder conectarse al vault y descargar los secretos requeridos y montarlos como archivos dentro de tu pod como se muestra en la imagen a continuación:

Para hacer eso, necesitamos realizar varios pasos como parte de la configuración que vamos a incluir en las próximas secciones del artículo

Habilitando la Autenticación de Kubernetes en Hashicorp

Lo primero que necesitamos hacer en esta etapa es habilitar la Autenticación de Kubernetes en Hashicorp. Este método permite a los clientes autenticarse con un Token de Cuenta de Servicio de Kubernetes. Hacemos eso con el siguiente comando:

 Vault auth enable kubernetes

Vault acepta un token de servicio de cualquier cliente en el clúster de Kubernetes. Durante la autenticación, Vault verifica que el token de la cuenta de servicio sea válido consultando un endpoint de revisión de tokens de Kubernetes. Ahora, necesitamos configurar este método de autenticación proporcionando la ubicación de nuestra API de Kubernetes, y para hacer eso, necesitamos ejecutar el siguiente comando:

 vault write auth/kubernetes/config 
    kubernetes_host="https://$KUBERNETES_PORT_443_TCP_ADDR:443"

Definiendo una Cuenta de Servicio de Kubernetes y Definiendo una Política

Ahora, crearemos una Cuenta de Servicio de Kubernetes que ejecutará nuestros pods, y a esta cuenta de servicio se le permitirá recuperar el secreto que generamos en el artículo anterior.

Para hacer eso, comenzaremos con la creación de la cuenta de servicio ejecutando este comando desde fuera del pod:

kubectl create sa internal-app

Esto creará una nueva cuenta de servicio bajo el nombre de internal-app, y ahora vamos a generar una política dentro del servidor de Hashicorp Vault usando este comando dentro del pod del servidor de vault:

 vault policy write internal-app - <<EOF
path "internal/data/database/config" {
  capabilities = ["read"]
}
EOF

Y ahora, asociamos esta política con la cuenta de servicio ejecutando este comando también dentro del pod del servidor de vault:

  vault write auth/kubernetes/role/internal-app 
    bound_service_account_names=internal-app 
    bound_service_account_namespaces=default 
    policies=internal-app 
    ttl=24h

Y eso es prácticamente toda la configuración que necesitamos hacer en el lado de Vault para poder inyectar secretos en pods usando Hashicorp Vault. Ahora, necesitamos configurar nuestra aplicación en consecuencia haciendo las siguientes modificaciones:

  • Especificar el ServiceAccountName en el despliegue para que sea el que creamos previamente: internal-app
  • Especificar las anotaciones específicas para inyectar los secretos de vault y la configuración de esos secretos.

Comencemos con el primer punto. Necesitamos agregar el serviceAccountName a nuestro archivo YAML de Manifiesto de Kubernetes como se muestra a continuación:

Inyectar Secretos en Pods: Definición del Nombre de la Cuenta de Servicio

Y con respecto al segundo punto, lo resolveríamos agregando varias anotaciones a nuestro despliegue, como se muestra a continuación:

Inyectar Secretos en Pods: Anotaciones

Las anotaciones utilizadas para inyectar secretos en pods son las siguientes:

  • vault.hashicorp.com/agent-inject: ‘true’: Esto le dice al inyector de vault que nos gustaría inyectar el agente sidecar en este despliegue y tener la configuración de Vault. Esto es necesario para hacer cualquier configuración adicional
  • vault.hashicorp.com/role: internal-app: Este es el rol de vault que vamos a usar cuando solicitemos secretos e información al vault para asegurarnos de que solo accedemos a los secretos que hemos permitido según la política que creamos en la sección anterior
  • vault.hashicorp.com/agent-inject-secret-secret-database-config.txt: internal/data/database/config: Esta será una anotación por cada secreto que planeamos agregar, y se compone de tres partes:
    • vault.hashicorp.com/agent-inject-secret- esta parte es fija
    • secret-database-config.txt esta parte será el nombre del archivo que se crea bajo /vault/secrets dentro de nuestro pod
    • internal/data/database/config Este es el camino dentro del vault de nuestro secreto para ser vinculado a ese archivo.

¡Y eso es todo! Si desplegamos ahora nuestro despliegue veremos las siguientes cosas:

  • Nuestra aplicación de despliegue se ha lanzado con tres contenedores en lugar de uno porque dos de ellos están relacionados con Hashicorp Vault, como puedes ver en la imagen a continuación:
Cómo inyectar secretos en pods para mejorar la seguridad con Hashicorp Vault en 5 minutos
  • vault-agent-init será el contenedor que establece la conexión con el servidor de vault porque cualquier contenedor comienza y realiza la primera descarga e inyección de secretos en el pod según la configuración proporcionada.
  • vault-agent será el contenedor que se ejecuta como un observador para detectar cualquier modificación en los secretos relacionados y actualizarlos.
Cómo inyectar secretos en pods para mejorar la seguridad con Hashicorp Vault en 5 minutos

Y ahora, si vamos al contenedor principal, veremos en la ruta /vault/secrets que el secreto ha sido finalmente inyectado como se esperaba:

Cómo inyectar secretos en pods para mejorar la seguridad con Hashicorp Vault en 5 minutos

Y así es como fácilmente y sin ningún conocimiento sobre la aplicación subyacente podemos inyectar secretos en pods usando Hashicorp Vault.

📚 Want to dive deeper into Kubernetes? This article is part of our comprehensive Kubernetes Architecture Patterns guide, where you’ll find all fundamental and advanced concepts explained step by step.

OpenLens vs Lens: Una nueva batalla comienza en enero de 2023

OpenLens vs Lens: A New Battle Starting in January 2023

Introducción

Ya hablamos sobre Lens varias veces en diferentes artículos, pero hoy lo traigo aquí OpenLens porque después del lanzamiento de Lens 6 a finales de julio han surgido muchas preguntas, especialmente en relación con su cambio y la relación con el proyecto OpenLens, así que pensé que podría ser muy interesante reunir algunos de estos datos en el mismo lugar para que ninguno de ustedes esté bastante confundido. Así que intentaré explicar y responder las principales preguntas que puedan tener en este momento.

¿Qué es OpenLens?

OpenLens es el proyecto de código abierto que está detrás del código que soporta la funcionalidad principal de Lens, el software que te ayuda a gestionar y ejecutar tus Clústeres de Kubernetes. Está disponible en GitHub aquí (https://github.com/lensapp/lens) y es totalmente de código abierto y distribuido bajo una Licencia MIT. En sus propias palabras, esta es la definición:

Este repositorio ("OpenLens") es donde el Equipo Lens desarrolla el producto Lens IDE junto con la comunidad. Está respaldado por varios pioneros del ecosistema Kubernetes y nativo de la nube. Este código fuente está disponible para todos bajo la licencia MIT

¿OpenLens vs Lens?

Entonces, la pregunta principal que podrías tener en este momento es cuál es la diferencia entre Lens y OpenLens. La principal diferencia es que Lens está construido sobre OpenLens, incluyendo algunos software y bibliotecas adicionales con diferentes licencias. Es desarrollado por el equipo de Mirantis (la misma empresa que posee Docker Enterprise) y se distribuye bajo un EULA tradicional.

¿Lens va a ser privado?

Necesitamos comenzar diciendo que desde el principio Lens ha sido lanzado bajo un EULA tradicional, así que en ese aspecto no hay mucha diferencia, podemos decir que OpenLens es de código abierto pero Lens es Freeware o al menos era freeware en ese momento. Pero el 28 de julio tuvimos el lanzamiento de Lens 6 donde la diferencia entre los proyectos comenzó a surgir.

Como se comentó en el Blog de Mirantis, se han incluido muchos cambios y nuevas capacidades, pero además de eso también se ha revelado la visión. Como dice el equipo de Mirantis, no se detienen en el nivel actual que Lens tiene hoy para gestionar el clúster de Kubernetes, quieren ir más allá proporcionando también una versión web de Lens para simplificar aún más el acceso, también extender su alcance más allá de Kubernetes, y así sucesivamente.

Entonces, puedes admitir que esta es una visión muy convincente y muy ambiciosa al mismo tiempo y es por eso que también están haciendo algunos cambios en la licencia y el modelo, de los cuales vamos a hablar a continuación.

¿Lens sigue siendo gratuito?

Ya comentamos que Lens siempre se lanzó bajo un EULA tradicional, por lo que no era de código abierto como otros proyectos, como su núcleo en OpenLens, pero era gratuito para usar. Con el lanzamiento el 28 de julio, esto está cambiando un poco para apoyar su nueva visión.

Están lanzando un nuevo modelo de suscripción dependiendo del uso que estés haciendo de la herramienta y el enfoque es muy similar al que hicieron en su momento con Docker Desktop, si recuerdas que manejamos eso en un artículo también.

  • Lens Personal: las suscripciones son para uso personal, educación y startups (menos de $10 millones en ingresos anuales o financiación). Son gratuitas.
  • Lens Pro: se requieren suscripciones para uso profesional en empresas más grandes. El precio es de $19.90 por usuario/mes o $199 por usuario/año.

La nueva licencia se aplicó con el lanzamiento de Lens 6 el 28 de julio, pero han proporcionado un Período de Gracia hasta enero de 2023 para que puedas adaptarte a este nuevo modelo.

¿Debería dejar de usar Lens ahora?

Esto es, como siempre, decisión tuya, pero las cosas van a ser las mismas hasta enero de 2023 y en ese momento, necesitas formalizar tu situación con Lens y Mirantis. Si estás en la situación de una licencia Lens Personal porque trabajas para una startup o de código abierto, puedes continuar haciéndolo sin ningún problema. Si ese no es el caso, depende de la empresa si las características adicionales que están proporcionando ahora y también la visión para el futuro justifican la inversión que necesitas hacer en la licencia Lens Pro.

Siempre tendrás la opción de cambiar de Lens a OpenLens, no será 100% lo mismo, pero las funcionalidades y el enfoque principales en este momento seguirán siendo los mismos y el proyecto seguramente estará muy, muy activo. Y también, como Mirantis ya confirmó en el mismo blog: «No hay cambios en la licencia de OpenLens ni en ningún otro proyecto de código abierto upstream utilizado por Lens Desktop.» Así que no puedes esperar que la misma situación ocurra si estás cambiando a OpenLens o ya usando OpenLens.

¿Cómo puedo instalar OpenLens?

La instalación de OpenLens es un poco complicada porque necesitas generar tu compilación desde el código fuente, pero para facilitar ese camino ha habido varias personas increíbles que están haciendo eso en sus repositorios de GitHub, como Muhammed Kalkan, que está proporcionando un repositorio con las últimas versiones con solo componentes de código abierto para las principales plataformas (Windows, macOS X (Intel y Silicon) o Linux) disponible aquí:

¿Qué características pierdo si cambio a OpenLens?

Seguramente habrá algunas características que perderás si cambias de Lens a OpenLens, que son las que se proporcionan utilizando las piezas de software con licencia. Aquí incluimos una lista no exclusiva de nuestras experiencias usando ambos productos:

  • Sincronización de Cuenta: Todas las capacidades de tener todos tus Clústeres de Kubernetes bajo tu Cuenta Lens y sincronizados no estarán disponibles en OpenLens. Dependerás del contenido del archivo kubeconfig.
  • Espacios: La opción de tener tu configuración compartida entre diferentes usuarios que pertenecen al mismo equipo no está disponible en OpenLens.
  • Escaneo de Imagen: Una de las nuevas capacidades de Lens 6 es la opción de escanear la imagen de los contenedores desplegados en el clúster, pero esto no está disponible en OpenLens.

📚 Want to dive deeper into Kubernetes? This article is part of our comprehensive Kubernetes Architecture Patterns guide, where you’ll find all fundamental and advanced concepts explained step by step.

Hadolint: Mejores prácticas para tus Dockerfiles en 3 modelos diferentes

Hadolint: Mejores prácticas para tus Dockerfiles en 3 modelos diferentes

Introducción

Hadolint es una herramienta de código abierto que te ayudará a asegurar que todos los Dockerfiles que crees sigan todas las mejores prácticas de Dockerfile disponibles de manera automatizada. Hadolint, como el número ya sugiere, es una herramienta linter y, debido a eso, también puede ayudarte a enseñarte todas estas mejores prácticas al crear Dockerfiles por ti mismo. Ya hablamos sobre la optimización del tamaño de la imagen del contenedor, pero hoy vamos a intentar cubrirlo más a fondo.

Hadolint es una herramienta más pequeña escrita en Haskell que analiza el Dockerfile en un AST y realiza reglas sobre el AST. Se apoya en ShellCheck para analizar el código Bash dentro de las instrucciones RUN, como se muestra en la imagen a continuación:

Hadolint: Mejores prácticas para tus Dockerfiles en 3 modelos diferentes

Hay varias maneras de ejecutar la herramienta, dependiendo de lo que intentes lograr, y hablaremos un poco sobre las diferentes opciones.

Ejecutándolo como una herramienta independiente

Esta es la primera forma en que podemos ejecutarlo como una herramienta independiente completa que puedes descargar desde aquí, y necesitará hacer el siguiente comando.

 hadolint <Dockerfile path>

Se ejecutará contra él y mostrará cualquier problema que se encuentre, como puedes ver en la imagen a continuación:

Ejecución de Hadolint

Para cada uno de los problemas encontrados, mostrará la línea donde se detecta el problema, el código de la verificación de mejores prácticas de Dockerfile que se está realizando (DL3020), la severidad de la verificación (error, advertencia, información, etc.), y la descripción del problema.

Para ver todas las reglas que se están ejecutando, puedes revisarlas en el Wiki de GitHub, y todas ellas están basadas en las mejores prácticas de Dockerfile publicadas directamente por Docker en su página web oficial aquí.

Para cada una de ellas, encontrarás una página wiki específica con toda la información que necesitas sobre el problema y por qué esto es algo que debería cambiarse, y cómo debería cambiarse, como puedes ver en la imagen a continuación:

Página del Wiki de Hadolint en GitHub

Capacidad de Ignorar Reglas

Puedes ignorar algunas reglas si no quieres que se apliquen porque hay algunos falsos positivos o simplemente porque las verificaciones no están alineadas con las mejores prácticas de Dockerfile utilizadas en tu organización. Para hacer eso, puedes incluir un parámetro —ignore con la regla a aplicar:

 hadolint --ignore DL3003 --ignore DL3006 <Dockerfile>

Ejecutándolo como Contenedor Docker

Además, la herramienta está disponible como un contenedor Docker en los siguientes repositorios:

docker pull hadolint/hadolint
# O
docker pull ghcr.io/hadolint/hadolint

Y esto te ayudará a introducirlo en tu Integración Continua y Despliegue Continuo o simplemente para ser usado en tu entorno local si prefieres no instalar software localmente.

Ejecutándolo dentro de VS Code

Como muchos linters, es esencial tenerlo cerca de tu entorno de desarrollo; esta vez no es diferente. Nos gustaría tener las mejores prácticas de Dockerfile relativas al editor mientras estamos escribiendo por dos razones principales:

  • Tan pronto como obtengas el problema, lo solucionarás más rápido para que el código siempre tenga mejor calidad
  • Tan pronto como sepas del problema, no lo volverás a cometer en desarrollos nuevos.

Tendrás Hadolint como parte de las Extensiones: Marketplace, y puedes instalarlo:

Extensión de Hadolint para VS Code


Una vez que hayas hecho eso, cada vez que abras un Dockerfile, validarás contra todas estas mejores prácticas de Dockerfile, y mostrará los problemas detectados en la vista de Problemas, como puedes ver en la imagen a continuación:

Ejecución de la Extensión de Hadolint para VS Code

Y esos problemas serán reevaluados tan pronto como modifiques y guardes el Dockerfile nuevamente, por lo que siempre verás la versión en vivo del problema detectado contra las mejores prácticas de Dockerfile.

Configuración de TIBCO BW Hashicorp Vault: Más Potente y Mejor Protegida en 3 Pasos

Configuración de TIBCO BW Hashicorp Vault: Más Potente y Mejor Protegida en 3 Pasos

Introducción

Este artículo tiene como objetivo mostrar la Configuración de TIBCO BW Hashicorp Vault para integrar su aplicación TIBCO BW con los secretos almacenados en Hashicorp Vault, principalmente para la externalización y gestión de recursos de contraseñas y credenciales.

Como probablemente sepa, en la aplicación TIBCO BW, la configuración se almacena en Propiedades a diferentes niveles (propiedades de Módulo o Aplicación). Puede leer más sobre ellas aquí. Y el propósito principal de esas propiedades es proporcionar flexibilidad a la configuración de la aplicación.

Estas propiedades pueden ser de diferentes tipos, como String, Integer, Long, Double, Boolean y DateTime, entre otros recursos técnicos dentro de TIBCO BW, como se muestra en la imagen a continuación:

Configuración de TIBCO BW Hashicorp Vault: Tipos de Propiedades BW

La integración de TIBCO BW Hashicorp Vault afectará solo a aquellas propiedades de tipo Contraseña (al menos hasta la versión 2.7.2/6.8.1 de BW). La razón detrás de esto es que esas propiedades son el tipo de datos relevantes para la información que es sensible y necesita ser segura. Otros conceptos pueden ser gestionados a través de componentes estándar de Kubernetes como ConfigMaps.

Definición de la Aplicación BW

Vamos a comenzar con una aplicación sencilla, como puede ver en la imagen a continuación:

Configuración de TIBCO BW Hashicorp Vault: Ejemplo de Propiedad

Solo un temporizador simple que se ejecutará una vez e insertará la hora actual en la base de datos PostgreSQL. Usaremos Hashicorp Vault para almacenar la contraseña del usuario de la base de datos para poder conectarnos a ella. El nombre de usuario y la cadena de conexión residirán en un ConfigMap.

Omitiremos la parte de la configuración relacionada con el despliegue de los Contenedores de la aplicación TIBCO BW y enlazaremos a un ConfigMap. Tiene un artículo que cubre eso en detalle en caso de que necesite seguirlo, y nos centraremos solo en el tema relacionado con la integración de TIBCO BW Hashicorp Vault.

Así que necesitaremos decirle a TIBCO BW que la contraseña del Recurso Compartido JDBC estará vinculada a la configuración de Hashicorp Vault, y para hacer eso, lo primero es haber vinculado la Contraseña de los Recursos Compartidos a una Propiedad de Módulo como se muestra en la imagen a continuación:

Configuración de TIBCO BW Hashicorp Vault: Contraseña vinculada a Propiedad de Módulo

Ahora, necesitamos decirle a esta Propiedad de Módulo que está vinculada a Hashicorp Vault, y lo haremos en la Vista de Propiedades de la Aplicación, seleccionando que esta propiedad está vinculada a una Solución de Gestión de Credenciales como se muestra en la imagen a continuación:

Configuración de TIBCO BW Hashicorp Vault: Configuración de Gestión de Credenciales para Propiedad

Y es ahora cuando establecemos la relación de TIBCO BW Hashicorp Vault. Necesitamos hacer clic directamente en el signo más verde, y tendremos una ventana modal que nos pedirá la tecnología de gestión de credenciales que vamos a usar y los datos necesarios para cada una de ellas, como puede ver en la siguiente imagen:

Configuración de TIBCO BW Hashicorp Vault: Configuración de Gestión de Credenciales para Propiedad

Seleccionaremos Hashicorp Vault como el proveedor. Luego necesitaremos proporcionar tres atributos que ya comentamos en el artículo anterior cuando comenzamos a crear secretos en Hashicorp Vault:

  • Nombre del Secreto: este es el nombre del secreto después de la ruta raíz del elemento.
  • Clave del Secreto: Esta es la clave dentro del propio secreto
  • Ruta de Montaje: Esta es la ruta raíz del secreto

Para obtener más detalles sobre estos tres conceptos, por favor, consulte nuestro artículo sobre cómo crear secretos en Hashicorp Vault.

Así que con todo esto, tenemos prácticamente todo lo que necesitamos para conectarnos a Hashicorp Vault y obtener el secreto, y desde el lado de TIBCO BW BusinessStudio, todo está hecho; podemos generar el archivo EAR y desplegarlo en Kubernetes porque aquí está la última parte de nuestra configuración.

 Despliegue en Kubernetes

Hasta este momento, ya hemos proporcionado la siguiente información:

  • Proceso BW que tiene el inicio de sesión para conectarse a la Base de Datos e insertar información
  • Enlace entre la propiedad de contraseña utilizada para conectar y la definición del Secreto de Hashicorp

Así que, prácticamente todo está ahí, pero falta un concepto. ¿Cómo se conectará el Pod de Kubernetes a Hashicorp una vez que el pod esté desplegado? Hasta este punto, no proporcionamos la ubicación del servidor de Hashicorp Vault del método de autenticación para conectarse a él. Esta es la parte que falta de la integración de TIBCO BW Hashicorp Vault y será parte del archivo YAML de Despliegue de Kubernetes.

Lo haremos usando las siguientes propiedades de entorno en este ejemplo:

Configuración de TIBCO BW Hashicorp Vault: Variables de Entorno de Hashicorp
  • HASHICORP_VAULT_ADDR: Esta variable apuntará a donde se encuentra el servidor de Hashicorp Vault
  • HASHICORP_VAULT_AUTH: Esta variable indicará qué opciones de autenticación se utilizarán. En nuestro caso, usaremos la de token como usamos en el artículo anterior
  • HASHICORP_VAULT_KV_VERSION: Esta variable indica qué versión de la solución de almacenamiento KV estamos usando y será dos por defecto.
  • HASHICORP_VAULT_TOKEN: Este será solo el valor del token para poder autenticarse contra el servidor de Hashicorp Vault

Si está utilizando otros métodos de autenticación o simplemente quiere saber más sobre esas propiedades, por favor, eche un vistazo a esta documentación de TIBCO.

Con todo eso agregado a las propiedades de entorno de nuestra aplicación TIBCO BW, podemos ejecutarla, y obtendremos una salida similar a esta, que muestra que la integración de TIBCO BW Hashicorp Vault se ha realizado y la aplicación pudo iniciarse sin ningún problema

Configuración de TIBCO BW Hashicorp Vault: Ejecución de ejemplo

Crea Secretos en Hashicorp Vault Usando 2 Formas Fáciles

Crea Secretos en Hashicorp Vault Usando 2 Formas Fáciles

Introducción

Crear secretos en Hashicorp Vault es una de las cosas más importantes y relevantes que puedes hacer una vez que has instalado Hashicorp Vault en tu entorno, probablemente recuperando y obteniendo estos secretos de los componentes que los necesitan. Pero en el artículo de hoy, nos centraremos en la primera parte para que puedas aprender lo fácil que es crear secretos en Hashicorp Vault.

En artículos anteriores comentamos la importancia de Hashicorp Vault y el proceso de instalación, como puedes leer aquí. Por lo tanto, en este punto, ya tenemos nuestra bóveda lista para comenzar a trabajar con ella completamente inicializada y desbloqueada para poder comenzar a atender solicitudes.

Crear Secretos en Hashicorp Vault usando Comandos CLI de Hashicorp Vault

Todos los comandos que realizaremos usarán un componente crítico llamado Hashicorp Vault CLI, y notarás eso porque todos nuestros comandos comenzarán con vault. Para ser honesto, ya comenzamos con eso en el artículo anterior; si recuerdas, ya ejecutamos algunos de estos comandos para inicializar o desbloquear la bóveda, pero ahora este será nuestro componente principal para interactuar.

Lo primero que necesitamos hacer es poder iniciar sesión en la bóveda, y para hacer eso; vamos a usar el token raíz que se nos proporcionó cuando inicializamos la bóveda; vamos a almacenar esta bóveda en una variable de entorno para que sea fácil trabajar con ella. Todos los comandos que vamos a ejecutar ahora estarán dentro del pod del servidor del agente de la bóveda, como se muestra en la imagen a continuación:

Crear Secretos en Hashicorp Vault: Detectando Pod del Servidor de la Bóveda

Una vez que estemos dentro, vamos a hacer el comando de inicio de sesión con la siguiente sintaxis:

 vault login 

Y obtendremos una salida similar a esta:

Crear Secretos en Hashicorp Vault: Iniciando sesión en Hashicorp Vault

Si no proporcionamos el token de antemano, la consola pedirá que se escriba el token posteriormente, y se ocultará automáticamente, como puedes ver en la imagen a continuación:

Crear Secretos en Hashicorp Vault: Iniciando sesión sin Token proporcionado

Después de este punto, ya estamos conectados a la bóveda, por lo que podemos comenzar a escribir comandos para crear secretos en Hashicorp Vault. Comencemos con ese proceso.

Para comenzar con nuestro proceso de creación de secretos en Hashicorp Vault, primero necesitamos hacer o ser más precisos con la sintaxis de Hashicorp Vault para habilitar una ruta de secreto que puedes pensar como la ruta raíz a la que estarán relacionados todos tus secretos. Si estamos hablando de tener secretos para diferentes aplicaciones, cada ruta puede ser cada una de las aplicaciones, pero la organización de los secretos puede ser diferente dependiendo del contexto. Cubriremos eso con mucho más detalle en los siguientes artículos.

Para habilitar la ruta de secreto para comenzar la creación de secretos en Hashicorp Vault, escribiremos el siguiente comando:

 vault secrets enable -path=internal kv-v2

Eso habilitará un almacén de secretos del tipo kv-v2 (almacén de clave-valor en su v2), y la ruta será “internal,” por lo que todo lo que creemos después de eso estará bajo esta ruta raíz “internal.”

Y ahora, vamos a hacer la creación del secreto en Hashicorp Vault, y como estamos usando un almacén de clave-valor, la sintaxis también está relacionada con eso porque vamos a “poner” un secreto usando el siguiente comando:

 vault kv put internal/database/config username="db-readonly-username" password="db-secret-password"

Eso creará dentro de la ruta interna una ruta hija /database/config donde almacenará dos claves:

  • username que tendrá el valor db-readonly-username
  • password que tendrá el valor db-secret-password

Como puedes ver, es bastante fácil crear nuevos secretos en la Bóveda vinculados a la ruta, y si deseas recuperar su contenido, también puedes hacerlo usando el CLI de la Bóveda, pero esta vez usando el comando get como se muestra en el fragmento a continuación:

 vault kv get internal/database/config

Y la salida será similar a la que se muestra a continuación:

Crear Secretos en Hashicorp Vault: Recuperando Secretos de la Bóveda

Esto te ayudará a interactuar con el contenido de tu almacén para recuperar, agregar o actualizar lo que ya tienes allí. Una vez que tengas todo listo allí, podemos pasar al lado del cliente para configurarlo para recopilar todos estos datos como parte de su flujo de trabajo de ciclo de vida.

Crear Secretos en Hashicorp Vault usando REST API

El CLI de Hashicorp Vault simplifica la interacción con el servidor de la bóveda, pero toda la interacción entre el CLI y el servidor ocurre a través de una REST API que el servidor expone y el cliente CLI consume. Proporciona una sintaxis simplificada al usuario y traduce los parámetros proporcionados en solicitudes REST al servidor, pero también puedes usar solicitudes REST para ir directamente al servidor. Por favor, consulta este artículo en la documentación oficial para obtener más detalles sobre la REST API.

Instalación de Hashicorp Vault en Kubernetes: Rápida y Sencilla en 3 Pasos Fáciles

Instalación de Hashicorp Vault en Kubernetes: Rápida y Sencilla en 3 Pasos Fáciles

Introducción

En este artículo, vamos a cubrir la instalación de Hashicorp Vault en Kubernetes. Hashicorp Vault se ha convertido en uno de los estándares de la industria cuando hablamos de gestionar secretos y datos sensibles en entornos de producción, y esto cubre implementaciones en la nube y no nativas de la nube. Pero especialmente en Kubernetes, este es un componente crítico. Ya hemos comentado que los Secretos de Kubernetes no están muy seguros por defecto, por lo que HashiCorp Vault resuelve ese problema.

Métodos de Instalación

Hashicorp Vault proporciona muchos métodos de instalación diferentes que puedes leer en su página oficial aquí; la mayoría todavía se centra en un entorno tradicional. Pero en resumen, estos son los que tienes disponibles:

  • Instalar desde el gestor de paquetes
  • Instalar desde un binario preexistente
  • Instalar desde el código fuente
  • Helm para Kubernetes

Como puedes imaginar, el camino que seguiremos aquí es el de Helm. Supongo que ya estás familiarizado con Helm, pero si no, echa un vistazo aquí, y si también estás en el proceso de crear charts de helm, este otro también puede ayudarte.

Chart de Helm para Hashicorp Vault

Para el propósito de este artículo, vamos a lo que se llama una instalación de hashicorp vault independiente, por lo que no vamos a crear en este post una arquitectura con Alta Disponibilidad (HA) que esté lista para producción, sino algo que pueda ayudarte a comenzar a jugar con la herramienta y ver cómo esta herramienta puede integrarse con otras que pertenecen al mismo entorno nativo de la nube. Para obtener más información sobre cómo implementar Hashicorp Vault en una configuración lista para producción, consulta el siguiente enlace.

Primero necesitamos instalar el chart de helm en nuestro entorno local, pero debemos tener mucho cuidado con la versión de helm que tenemos. Al escribir este artículo, la instalación de Hashicorp Vault requiere una versión de Helm 3.7+, por lo que primero debes verificar la versión que tienes instalada.

En caso de que estés ejecutando una versión anterior, obtendrás el siguiente error:

 Error: parse error at (vault/templates/_helpers.tpl:38): unclosed action

Puedes obtener más detalles sobre este problema de GitHub.

Al momento de escribir este artículo, la última versión de Helm es 3.9, pero esta versión genera un problema con AWS EKS con este error:

 Error: Kubernetes cluster unreachable: exec plugin: invalid apiVersion "client.authentication.k8s.io/v1alpha1."
Failed installing **** with helm

Puedes obtener más detalles sobre este problema de GitHub.

Entonces, en ese caso, la mejor manera de asegurarse de que no habrá un problema con la instalación de Hashicorp Vault es degradar a 3.8, y podrás implementar el chart de helm sin ningún problema.

Proceso de Instalación de Hashicorp Vault

Para proceder con la instalación de Hashicorp Vault, necesitamos ejecutar los siguientes comandos:

helm repo add hashicorp https://helm.releases.hashicorp.com
helm install vault hashicorp/vault

Esto instalará dos componentes diferentes: un único servidor de vault como parte de un StatefulSet y un vault-agent-injector para gestionar la inyección de la configuración de vault en los diversos componentes e implementaciones en los otros espacios de nombres.

Para que los pods se ejecuten, necesitamos inicializar y desellarlo antes de estar listos para usar. Para hacer eso, necesitamos entrar dentro del pod del servidor de vault y ejecutar los siguientes comandos:

 vault operator init

Esto generará varias cosas esenciales:

  • Generará las claves para poder desellar el vault y comenzar a usarlo. Mostrará un número diferente de claves, en nuestro ejemplo 5, y necesitarás al menos 3 de ellas para poder desellar el vault.
  • También generará un token raíz para poder iniciar sesión en la CLI e interactuar con el servidor para poder leer y escribir secretos.

Después de eso, necesitaremos ejecutar el siguiente comando al menos tres veces, proporcionando cada uno de ellos con una clave de desellado diferente:

 Vault operator unseal

Después de ese punto, todos los componentes están en ejecución y listos, y podemos concluir nuestra instalación de Hashicorp Vault y comenzar a interactuar con el vault para crear tus secretos.

Instalación de Hashicorp Vault: Todos los Componentes Listos

Bucles de Helm: Truco de Helm #1

Bucles de Helm: Truco de Helm #1

Introducción

Descubre cómo agregar bucles de Helm a tus helm charts para proporcionar un comportamiento más dinámico a tus Helm Charts.

Los Helm Charts se están convirtiendo en la solución predeterminada de facto cuando deseas empaquetar tu implementación de Kubernetes para poder distribuirla o instalarla rápidamente en tu sistema.

Definido varias veces como el apt para Kubernetes por su similitud con el antiguo gestor de paquetes de distribuciones GNU/Linux similares a Debian, parece seguir creciendo en popularidad cada mes en comparación con otras soluciones similares incluso más integradas en Kubernetes como Kustomize, como puedes ver en la imagen de Google Trends a continuación:

Helm Loops: Helm Charts vs Kustomize

Pero crear estos helm charts no es tan fácil como parece. Si ya has estado trabajando en ello, probablemente te hayas atascado en algún punto, o hayas pasado mucho tiempo tratando de hacer algunas cosas. Si es la primera vez que estás creando uno o intentando hacer algo avanzado, espero que todos estos trucos te ayuden en tu camino. Hoy vamos a cubrir uno de los trucos más importantes, y esos son los bucles de Helm.

Introducción a los Bucles de Helm

Si ves cualquier helm chart, seguro que tendrás muchos bloques condicionales. Prácticamente todo está cubierto bajo una estructura if/else basada en los archivos values.yml que estás creando. Pero esto se vuelve un poco complicado cuando hablamos de bucles. Pero lo bueno es que tendrás la opción de ejecutar un bucle de helm dentro de tus helm charts usando la primitiva range.

¿Cómo crear un Bucle de Helm?

El uso de la primitiva range es bastante simple, ya que solo necesitas especificar el elemento que deseas iterar, como se muestra en el fragmento a continuación:

{{- range .Values.pizzaToppings }}
- {{ . | title | quote }}
{{- end }}    

Este es un ejemplo bastante simple donde el yaml iterará sobre los valores que has asignado a la estructura pizzaToppings en tu values.yml.

Hay algunos conceptos a tener en cuenta en esta situación:

  • Puedes acceder fácilmente a todo dentro de esta estructura que estás recorriendo. Entonces, si el ingrediente de la pizza tiene campos adicionales, puedes acceder a ellos con algo similar a esto:
{{- range.Values.pizzaToppings }}
- {{ .ingredient.name | title | quote }}
{{- end }}    

Y esto accederá a una estructura similar a esta en tu values.yml:

 pizzaToppings:
	- ingredient:
		name: Piña
		weight: 3

Lo bueno es que puedes acceder a su atributo subyacente sin replicar toda la jerarquía principal hasta llegar a la estructura de bucle porque dentro de la sección de rango, el alcance ha cambiado. Nos referiremos a la raíz de cada elemento que estamos iterando.

¿Cómo acceder a elementos principales dentro de un Bucle de Helm?

En la sección anterior, cubrimos cómo podemos acceder fácilmente al atributo interno dentro de la estructura de bucle debido al cambio de alcance, lo que también tiene un problema. En caso de que quiera acceder a algún elemento en el padre de mi archivo values.yml o en algún lugar fuera de la estructura, ¿cómo puedo acceder a ellos?

Lo bueno es que también tenemos una gran respuesta para eso, pero puedes llegar allí. Necesitamos entender un poco sobre los alcances en Helm.

Como se comentó, . se refiere al elemento raíz en el alcance actual. Si nunca has definido una sección de rango u otra primitiva que cambie el contexto, . siempre se referirá a la raíz de tu values.yml. Es por eso que cuando ves un helm chart, ves todas las estructuras con la siguiente forma de trabajar: .Values.x.y.z, pero ya hemos visto que cuando tenemos una sección range, esto está cambiando, por lo que esta no es una buena manera.

Para resolver eso, tenemos el contexto $ que se refiere constantemente a la raíz del values.yml sin importar cuál sea el alcance actual. Así que eso significa que si tengo el siguiente values.yml:

base:
	- type: slim 
pizzaToppings:
	- ingredient:
		name: Piña
		weight: 3
	- ingredient:
		name: Manzana
		weight: 3

Y quiero referirme al tipo base dentro de la sección de rango similar a antes, puedo hacerlo usando el siguiente fragmento:

{{- range .Values.pizzaToppings }}
- {{ .ingredient.name | title | quote }} {{ $.Values.base.type }}
{{- end }}    

Eso generará la siguiente salida:

 - Piña slim
 - Manzana slim

¡Así que espero que este truco de helm chart te ayude con la creación, modificación o mejora de tus helm charts mejorados en el futuro utilizando bucles de helm sin ninguna preocupación adicional!

Operador de Registro de BanzaiCloud en Kubernetes Simplificado en 5 minutos

Operador de Registro de BanzaiCloud en Kubernetes Simplificado en 5 minutos

En el artículo anterior, describimos qué capacidad proporciona BanzaiCloud Logging Operator y sus características principales. Así que hoy vamos a ver cómo podemos implementarlo.

Lo primero que necesitamos hacer es instalar el operador en sí, y para hacerlo, tenemos un chart de helm a nuestra disposición, así que lo único que necesitaremos hacer son los siguientes comandos:

 helm repo add banzaicloud-stable https://kubernetes-charts.banzaicloud.com
helm upgrade --install --wait --create-namespace --namespace logging logging-operator banzaicloud-stable/logging-operator

Eso creará un namespace de logging (en caso de que aún no lo tengas), y desplegará los componentes del operador en sí, como puedes ver en la imagen a continuación:

Operador de Registro de BanzaiCloud en Kubernetes Simplificado en 5 minutos
BanzaiCloud Logging Operator instalado usando HelmChart

Así que, ahora podemos empezar a crear los recursos que necesitamos usando el CRD que comentamos en el artículo anterior, pero para hacer un resumen. Estos son los que tenemos a nuestra disposición:

  • logging – El recurso de logging define la infraestructura de logging para tu clúster que recoge y transporta tus mensajes de log. También contiene configuraciones para Fluentd y Fluent-bit.
  • output / clusteroutput – Define una Salida para un flujo de logging, donde se envían los mensajes de log. output será basado en namespace, y clusteroutput será basado en clúster.
  • flow / clusterflow – Define un flujo de logging usando filtros y salidas. El flujo dirige los mensajes de log seleccionados a las salidas especificadas. flow será basado en namespace, y clusterflows serán basados en clúster.

Así que, primero que nada, vamos a definir nuestro escenario. No quiero hacer algo complejo; deseo que todos los logs que mis cargas de trabajo generen, sin importar en qué namespace estén, sean enviados a una instancia de Grafana Loki que también he instalado en ese clúster de Kubernetes en un endpoint específico usando la configuración Simple Scalable para Grafana Loki.

Así que, comencemos con los componentes que necesitamos. Primero, necesitamos un objeto de Logging para definir mi infraestructura de Logging, y lo crearé con el siguiente comando.

kubectl -n logging apply -f - <<"EOF"
apiVersion: logging.banzaicloud.io/v1beta1
kind: Logging
metadata:
  name: default-logging-simple
spec:
  fluentd: {}
  fluentbit: {}
  controlNamespace: logging
EOF

Mantendremos la configuración predeterminada para fluentd y fluent-bit solo por el bien del ejemplo, y más adelante en próximos artículos, podemos hablar sobre un diseño específico, pero eso es todo.

Una vez que el CRD se procese, los componentes aparecerán en tu namespace de logging. En mi caso, que estoy usando un clúster de 3 nodos, veré 3 instancias de fluent-bit desplegadas como un DaemonSet y un solo ejemplo de fluentd, como puedes ver en la imagen a continuación:

Operador de Registro de BanzaiCloud en Kubernetes Simplificado en 5 minutos
Configuración de BanzaiCloud Logging Operator después de aplicar el CRD de Logging

Así que, ahora necesitamos definir la comunicación con Loki, y como me gustaría usar esto para cualquier namespace que pueda tener en mi clúster, usaré la opción ClusterOutput en lugar de la normal Output que está basada en namespace. Y para hacer eso, usaremos el siguiente comando (por favor asegúrate de que el endpoint sea el correcto; en nuestro caso, este es loki-gateway.default ya que está ejecutándose dentro del clúster de Kubernetes:

kubectl -n logging apply -f - <<"EOF"
apiVersion: logging.banzaicloud.io/v1beta1
kind: ClusterOutput
metadata:
 name: loki-output
spec:
 loki:
   url: http://loki-gateway.default
   configure_kubernetes_labels: true
   buffer:
     timekey: 1m
     timekey_wait: 30s
     timekey_use_utc: true
EOF

Y prácticamente tenemos todo; solo necesitamos un flujo para comunicar nuestra configuración de Logging al ClusterOutput que acabamos de crear. Y nuevamente, iremos con el ClusterFlow porque nos gustaría definir esto a nivel de Clúster y no de manera basada en namespace. Así que usaremos el siguiente comando:

 kubectl -n logging  apply -f - <<"EOF"
apiVersion: logging.banzaicloud.io/v1beta1
kind: ClusterFlow
metadata:
  name: loki-flow
spec:
  filters:
    - tag_normaliser: {}
  match:
    - select: {}
  globalOutputRefs:
    - loki-output
EOF

Y después de un tiempo para recargar la configuración (1-2 minutos más o menos), comenzarás a ver en los rastros de Loki algo como esto:

Operador de Registro de BanzaiCloud en Kubernetes Simplificado en 5 minutos
Grafana mostrando los logs enviados por el BanzaiCloud Logging Operator

Y eso indica que ya estamos recibiendo el envío de logs de los diferentes componentes, principalmente el elemento fluentd que configuramos en este caso. Pero creo que es mejor verlo gráficamente con Grafana:

Operador de Registro de BanzaiCloud en Kubernetes Simplificado en 5 minutos
Grafana mostrando los logs enviados por el BanzaiCloud Logging Operator

¡Y eso es todo! Y cambiar nuestra configuración de logging es tan simple como cambiar el componente CRD que definimos, aplicando coincidencias y filtros, o enviándolo a un nuevo lugar. De manera sencilla, tenemos esto completamente gestionado.

📚 Want to dive deeper into Kubernetes? This article is part of our comprehensive Kubernetes Architecture Patterns guide, where you’ll find all fundamental and advanced concepts explained step by step.