Solución para la transformación fallida de entrada XSLT en BusinessWorks

Solución para la transformación fallida de entrada XSLT en BusinessWorks

Resolviendo uno de los problemas más comunes de los desarrolladores usando BusinessWorks

El Transformation failed for XSLT input es uno de los mensajes de error más comunes que podrías ver al desarrollar usando las herramientas de TIBCO BusinessWorks. Entender lo que el mensaje está diciendo es esencial para proporcionar una solución rápida.

He visto desarrolladores necesitando horas y horas tratando de solucionar este tipo de error cuando la mayoría de las veces, toda la información que estás recibiendo está justo frente a ti, pero necesitas entender por qué el motor lo está pidiendo.

Pero primero proporcionemos un poco de contexto. ¿De qué error estamos hablando? Estoy hablando de algo como lo que puedes ver en el registro de trazas a continuación:

...
com.tibco.pvm.dataexch.xml.util.exceptions.PmxException: PVM-XML-106027: Transformation failed for XSLT input '<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:tns1="http://www.tibco.com/pe/WriteToLogActivitySchema" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:tib="http://www.tibco.com/bw/xslt/custom-functions" version="2.0"><xsl:param name="Mapper2"/><xsl:template name="Log-input" match="/"><tns1:ActivityInput><message><xsl:value-of select="tib:add-to-dateTime($Mapper2/primitive,0,0,1,0,0,0)"/></message></tns1:ActivityInput></xsl:template></xsl:stylesheet>'
	at com.tibco.pvm.infra.dataexch.xml.genxdm.expr.IpmxGenxXsltExprImpl.eval(IpmxGenxXsltExprImpl.java:65)
	at com.tibco.bx.core.behaviors.BxExpressionHelper.evalAsSubject(BxExpressionHelper.java:107)
...

¿Te suena más familiar ahora? Como ya dije, todos los desarrolladores de TIBCO BusinessWorks se han enfrentado a eso. Como dije, he visto a algunos de ellos luchando o incluso rehaciendo el trabajo repetidamente sin encontrar una solución adecuada. Pero la idea aquí es tratar de resolverlo de manera eficiente y rápida.

Comenzaré con las advertencias iniciales: Evitemos re-codificar, rehacer algo que debería funcionar pero no está funcionando, porque no estás ganando en ningún escenario:

  • Si lo rehaces y no funcionó, pierdes x2 tiempo creando algo que ya tienes, y aún estás atascado.
  • Si lo rehaces y funciona, no sabes qué estaba mal, por lo que te enfrentarás a ello nuevamente en breve.

Entonces, ¿cómo funciona esto? Usemos este proceso:

Recopilar —> Analizar —> Entender —> Corregir.

Escenario

Primero, necesitamos recopilar datos, y la mayoría de las veces, como dije, es suficiente con el registro de trazas que tenemos, pero en algún momento, podrías necesitar requerir el código de tu proceso para detectar el error y la solución.

Así que comenzaremos con este código fuente que puedes ver en la captura de pantalla a continuación y la siguiente explicación:

Solución para la transformación fallida de entrada XSLT en BusinessWorks

Tenemos un Mapper que está definiendo un esquema con un elemento int que es una opción, y no estamos proporcionando ningún valor:

Solución para la transformación fallida de entrada XSLT en BusinessWorks

Y luego estamos usando la fecha para imprimir un registro, agregando un día más a esa fecha:

Solución para la transformación fallida de entrada XSLT en BusinessWorks

Solución

Primero, necesitamos entender el mensaje de error. Cuando recibimos un mensaje de error titulado `Transformation failed for XSLT input que dice precisamente esto:

Intenté ejecutar el XSLT que está relacionado con una actividad, y fallé debido a un error técnico

Como probablemente ya sabes, cada una de las actividades de BusinessWorks ejecuta una Transformación XSL internamente para hacer el mapeo de entrada; puedes verlo directamente en el Business Studio. Entonces, este error te está diciendo que este XSL interno está fallando.

Solución para la transformación fallida de entrada XSLT en BusinessWorks

Y la razón es un problema de tiempo de ejecución que no puede ser detectado en tiempo de diseño. Así que, para dejarlo claro, los valores de algunas de tus variables y la transformación fallan. Así que primero, deberías enfocarte en esto. Usualmente, toda la información está en el registro de trazas en sí, así que comencemos a analizar eso:

Solución para la transformación fallida de entrada XSLT en BusinessWorks

Entonces, veamos toda la información que tenemos aquí:

  • En primer lugar, podemos detectar qué actividad está fallando. Puedes hacerlo fácilmente si estás depurando localmente, pero si esto está sucediendo en el servidor puede ser más complicado; pero con esta información, tienes: Todo el XSLT en sí que está impreso en el registro de trazas, por lo que puedes fácilmente
  • También tienes un Causado por que te está diciendo por qué está fallando:
    • Puedes tener varias oraciones de Causado por que deben leerse en modo de cascada, por lo que la más baja es el problema raíz que genera el error para todos los demás arriba, así que deberíamos localizar eso primero.
Solución para la transformación fallida de entrada XSLT en BusinessWorks

En este caso, el mensaje es bastante evidente, como puedes ver en la traza a continuación.

 com.tibco.xml.cxf.runtime.exceptions.FunctionException: XPath function {http://www.tibco.com/bw/xslt/custom-functions}add-to-dateTime exception: gregorian cannot be null.

Así que la función add-to-dateTime falla porque un argumento Gregoriano (es decir, una fecha) es nulo. Y eso es precisamente lo que está sucediendo en mi caso. Si proporciono un valor al parámetro… Voilà, ¡está funcionando!

Solución para la transformación fallida de entrada XSLT en BusinessWorks

 Resumen

Situaciones similares pueden ocurrir con diferentes causas raíz, pero las más comunes son:

  • Problema con elementos opcionales y no opcionales, por lo que un nulo llega a un punto donde debería.
  • Errores de validación porque el parámetro de entrada no coincide con la definición del campo.
  • Tipos XML extendidos que no son compatibles con la función utilizada.

¡Todos estos problemas pueden ser fácilmente y rápidamente resueltos siguiendo el razonamiento que explicamos en este post!

Así que, pongámoslo en práctica la próxima vez que veas a un colega con ese problema y ayúdalo a tener una experiencia de programación más eficiente!

Pod de Múltiples Contenedores: Cómo, Cuándo y Por Qué

city with high rise buildings during night time

Hablemos sobre la opción más peligrosa desde la perspectiva del diseño de Pods, ¡para que estés listo para usarla!

Pod de Múltiples Contenedores: Cómo, Cuándo y Por Qué

Foto de Timelab Pro en Unsplash

Una de las conversaciones habituales es sobre la composición y definición de componentes dentro de un Pod. Esto es normal para las personas que se trasladan de un despliegue tradicional a un entorno nativo de la nube, y la pregunta principal es: ¿Cuántos contenedores puedo tener dentro de un pod? 

Estoy seguro de que la mayoría de ustedes han escuchado o han hecho esa pregunta en algún momento de su viaje nativo de la nube, o incluso tienen esta duda internamente en este momento, y no hay duda en la respuesta: Un solo contenedor.

¡Espera, espera! ¡No dejes el post todavía! Sabemos que eso no es técnicamente cierto, pero es más fácil de entender inicialmente; solo puedes tener un pod haciendo una cosa.

Entonces, si ese es el caso, ¿por qué existen los pods de múltiples contenedores? Y lo más importante, si esta es la primera vez que escuchas ese concepto, ¿qué es un pod de múltiples contenedores?

Comencemos con la definición: Un pod de múltiples contenedores tiene más de un contenedor en su composición. Y cuando hablamos de múltiples contenedores, no estamos hablando de tener algunos initContainers para gestionar las dependencias. Aún así, estamos hablando de tener más de un contenedor ejecutándose simultáneamente y al mismo nivel, como puedes ver en la imagen a continuación:

Pod de Múltiples Contenedores: Cómo, Cuándo y Por Qué
Definición de Pod de Múltiples Contenedores

¿Kubernetes admite este modelo? Sí, por supuesto. Puedes definir dentro de tu sección de contenedores tantos contenedores como necesites. Entonces, desde un punto de vista técnico, no hay límite para tener tantos contenedores como necesites en el mismo pod. Pero la pregunta principal que deberías hacerte es:

¿Es esto lo que quieres hacer?

Un pod es la unidad más pequeña en Kubernetes como recordatorio. Despliegas y retiras pods, detienes y arrancas pods, reinicias pods, escalas pods. Así que cualquier cosa que esté dentro del mismo pod está altamente acoplada. Es como un paquete, y también comparten recursos. Así que es aún más crítico.

Imagina esta situación, me gustaría comprar un cuaderno, así que voy a la tienda y pido el cuaderno, pero no tienen un solo cuaderno. Aún así, tienen un paquete increíble: un cuaderno, un bolígrafo y una grapadora por solo $2 más que el precio de un solo cuaderno.

Así que piensas que este es un excelente precio porque estás obteniendo un bolígrafo y una grapadora por una pequeña parte de su precio si quisieras comprarlo por separado. Así que piensas que es una buena idea. Pero luego, recuerdas que también necesitas otros cuadernos para otros propósitos. Al final, necesitas diez cuadernos más, pero cuando necesitas comprarlos, también necesitas reconocer los diez bolígrafos y las diez grapadoras que ya no necesitas. OK, son más baratos, pero al final, estás pagando un precio razonable por algo que no necesitas. Así que, no es eficiente. Y lo mismo se aplica a la definición de la estructura del Pod.

Al final, ¿te mueves de despliegues monolíticos tradicionales a diferentes contenedores dentro de un pod para tener los mismos desafíos y problemas? ¿Cuál es el punto de hacer eso?

Ninguno.

Si no hay razón para tener dos contenedores estrechamente juntos, ¿por qué está permitido esto en la especificación de K8S? Porque esto es útil para algunos casos de uso y escenarios específicos. Hablemos de algunos de ellos.

  • Contenedores de Ayuda: Este es el más común y es que tienes diferentes contenedores dentro del pod. Aún así, uno es el principal, el que proporciona una capacidad de negocio o una característica, y el otro solo está ayudando de alguna manera.
  • Implementación del Patrón Sidecar: Otro enfoque común para tener esta composición es implementar el patrón sidecar. Así es como funciona al desplegar otro contenedor para realizar una capacidad específica. Lo has visto, por ejemplo, para Service Meshes, Arquitectura de Agregación de Logs, u otros componentes que siguen ese patrón.
  • Exportadores de Monitoreo: Otra cosa usual de ver es usar uno de estos contenedores para actuar como un exportador de las métricas de monitoreo del componente principal. Esto se ve usualmente en arquitecturas como Prometheus, donde cada pieza tiene su exportador para ser extraído del Servidor Prometheus

También hay hechos interesantes de compartir contenedores dentro de un pod porque, como se comentó, también comparten recursos como:

  • Volúmenes: Puedes, por ejemplo, definir una carpeta compartida para todos los diferentes contenedores dentro de un pod, para que un contenedor pueda leer información del otro para realizar su tarea de manera rápida y eficiente.
  • Comunicación Inter-procesos: Puedes comunicarte entre contenedores usando IPC para comunicarte de manera más eficiente.
  • Red: Los diferentes contenedores dentro de un pod también pueden acceder a puertos de otros contenedores simplemente alcanzando localhost.

Espero que este artículo te haya ayudado a entender por qué existe esta capacidad de tener muchos contenedores dentro del mismo pod, pero al mismo tiempo saber qué tipo de escenarios están usando este enfoque y tener algún razonamiento sobre si un nuevo caso de uso debería usar este enfoque o no.

📚 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 solucionar problemas de conexiones de red en tus cargas de trabajo de Kubernetes

blue UTP cord

Descubre Mizu: Visor de Tráfico para Kubernetes para facilitar este desafío y mejorar tu trabajo diario.

Cómo solucionar problemas de conexiones de red en tus cargas de trabajo de Kubernetes

Foto de Jordan Harrison en Unsplash

Una de las cosas más comunes que tenemos que hacer al probar y depurar nuestras cargas de trabajo nativas de la nube en Kubernetes es verificar la comunicación de red.

Podría ser para verificar el tráfico entrante que estás recibiendo para que podamos inspeccionar las solicitudes que estamos recibiendo y ver a qué estamos respondiendo y casos de uso similares. Estoy seguro de que esto suena familiar para la mayoría de ustedes.

Normalmente resuelvo eso usando tcpdump en el contenedor, similar a lo que haría en un entorno tradicional, pero esto no siempre es fácil. Dependiendo del entorno y la configuración, no puedes hacerlo porque necesitas incluir un nuevo paquete en la imagen de tu contenedor, hacer un nuevo despliegue para que esté disponible, etc.

Entonces, para resolver eso y otros problemas similares, descubrí una herramienta llamada Mizu, que me hubiera gustado encontrar hace unos meses porque me ayudaría mucho. Mizu es precisamente eso. En sus propias palabras:

Mizu es un visor de tráfico API simple pero poderoso para Kubernetes, que te permite ver toda la comunicación API entre microservicios a través de múltiples protocolos para ayudarte a depurar y solucionar regresiones.

Para instalar, es bastante sencillo. Necesitas obtener el binario y proporcionar el permiso correcto en tu computadora. Tienes un binario diferente para cada arquitectura, y en mi caso (Mac basado en Intel), estos son los comandos que ejecuté:

curl -Lo mizu github.com/up9inc/mizu/releases/latest/download/mizu_darwin_amd64 && chmod 755 mizu && mv mizu /usr/local/bin

Y eso es todo, luego tienes un binario en tu laptop que se conecta a tu clúster de Kubernetes usando la API de Kubernetes, por lo que necesitas tener configurado el contexto adecuado.

En mi caso, he desplegado un servidor nginx simple usando el comando:

 kubectl run simple-app --image=nginx --port 80

Y una vez que el componente ha sido desplegado, como se muestra en la captura de pantalla de Lens a continuación:

Ejecuté el comando para lanzar mizu desde mi laptop:

mizu tap

Y después de unos segundos, tengo frente a mí una página web abierta monitoreando todo el tráfico que ocurre en este pod:

Cómo solucionar problemas de conexiones de red en tus cargas de trabajo de Kubernetes

He expuesto el puerto de nginx usando el comando kubectl expose:

 kubectl expose pod/simple-app

Y después de eso, desplegué un pod temporal usando la imagen curl para comenzar a enviar algunas solicitudes con el comando que se muestra a continuación:

 kubectl run -it --rm --image=curlimages/curl curly -- sh

ahora he comenzado a enviar algunas solicitudes a mi pod nginx usando curl:

 curl -vvv http://simple-app:80 

Y después de algunas llamadas, pude ver mucha información frente a mí. En primer lugar, puedo ver las solicitudes que estaba enviando con todos los detalles de las mismas:

Cómo solucionar problemas de conexiones de red en tus cargas de trabajo de Kubernetes

Pero aún más importante, puedo ver un diagrama de mapa de servicios que muestra las dependencias y las llamadas gráficamente que ocurren en el pod con el tiempo de respuesta y también el uso del protocolo:

Cómo solucionar problemas de conexiones de red en tus cargas de trabajo de Kubernetes

Esto ciertamente no reemplazará una solución completa de observabilidad sobre una malla de servicios. Aún así, será una herramienta muy útil para agregar a tu cadena de herramientas cuando necesites depurar una comunicación específica entre componentes o escenarios similares. Como se comentó, es como un tcpdump de alto nivel para la comunicación de pods.

📚 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.

Por qué no deberías añadir una cuota de recursos usando el valor límite?

woman in blue denim jacket holding white paper

Si No Tienes Cuidado, Puedes Bloquear La Escalabilidad De Tus Cargas De Trabajo

Por qué no deberías añadir una cuota de recursos usando el valor límite?

Foto de Joshua Hoehne en Unsplash

Una de las grandes cosas sobre los desarrollos basados en contenedores es definir espacios de aislamiento donde tienes recursos garantizados como CPU y memoria. Esto también se extiende en entornos basados en Kubernetes a nivel de namespace, por lo que puedes tener diferentes entornos virtuales que no pueden exceder el uso de recursos a un nivel especificado.

Para definir eso, tienes el concepto de Cuota de Recursos que funciona a nivel de namespace. Basado en su propia definición (https://kubernetes.io/docs/concepts/policy/resource-quotas/)

Una cuota de recursos, definida por un objeto ResourceQuota, proporciona restricciones que limitan el consumo agregado de recursos por namespace. Puede limitar la cantidad de objetos que se pueden crear en un namespace por tipo, así como la cantidad total de recursos de cómputo que pueden ser consumidos por recursos en ese namespace.

Tienes varias opciones para definir el uso de estas Cuotas de Recursos, pero nos centraremos en este artículo en las principales de la siguiente manera:

  • limits.cpu: En todos los pods en un estado no terminal, la suma de los límites de CPU no puede exceder este valor.
  • limits.memory: En todos los pods en un estado no terminal, la suma de los límites de memoria no puede exceder este valor.
  • requests.cpu: En todos los pods en un estado no terminal, la suma de las solicitudes de CPU no puede exceder este valor.
  • requests.memory: En todos los pods en un estado no terminal, la suma de las solicitudes de memoria no puede exceder este valor.

Así que puedes pensar que esta es una gran opción para definir una cuota de limit.cpu y limit.memory, para asegurarte de que no excederás esa cantidad de uso por ningún medio. Pero necesitas tener cuidado con lo que esto significa, y para ilustrarlo usaré un ejemplo.

Tengo una sola carga de trabajo con un solo pod con la siguiente limitación de recursos:

  • requests.cpu: 500m
    • limits.cpu: 1
    • requests.memory: 500Mi
    • limits.memory: 1 GB

Tu aplicación es una aplicación basada en Java que expone un Servicio REST y ha configurado una regla de Escalador Horizontal de Pods para escalar cuando la cantidad de CPU excede su 50%.

Entonces, comenzamos en la situación primaria: con una sola instancia que requiere ejecutar 150 m de vCPU y 200 RAM, un poco menos del 50% para evitar el escalador. Pero tenemos una Cuota de Recursos sobre los límites del pod (1 vCPU y 1 GB) por lo que hemos bloqueado eso. Tenemos más solicitudes y necesitamos escalar a dos instancias. Para simplificar los cálculos, asumiremos que usaremos la misma cantidad de recursos para cada una de las instancias, y continuaremos de esa manera hasta llegar a 8 instancias. Así que veamos cómo cambian los límites definidos (el que limitará la cantidad de objetos que puedo crear en mi namespace) y la cantidad real de recursos que estoy usando:

Por qué no deberías añadir una cuota de recursos usando el valor límite?

Entonces, para una cantidad de recursos usados de 1.6 vCPU he bloqueado 8 vCPU, y en caso de que ese fuera mi Límite de Recursos, no puedo crear más instancias, aunque tengo 6.4 vCPU no usados que he permitido desplegar debido a este tipo de limitación no puedo hacerlo.

Sí, puedo asegurar el principio de que nunca usaré más de 8 vCPU, pero me he bloqueado muy temprano en esa tendencia afectando el comportamiento y la escalabilidad de mis cargas de trabajo.

Debido a eso, necesitas ser muy cuidadoso cuando estás definiendo este tipo de límites y asegurarte de lo que estás tratando de lograr porque al resolver un problema puedes estar generando otro.

Espero que esto pueda ayudarte a prevenir que este problema ocurra en tu trabajo diario o al menos tenerlo en cuenta cuando te enfrentes a escenarios similares.

📚 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.

Metadatos de Kubernetes: Potencia tus aplicaciones con contenido de tus pods

black laptop computer turned on on table

Descubre cómo extraer toda la información disponible para inyectarla en tus pods

Empodera tus pods con contenido de tu metadata de Kubernetes

Foto de James Harrison en Unsplash

La metadata de Kubernetes es cómo accederás a parte de la información de tus pods en tu aplicación en tiempo de ejecución. Cuando te mueves de un tipo de desarrollo tradicional a uno nativo de la nube, usualmente necesitas acceder a alguna información disponible de manera predeterminada en un entorno convencional.

Esto sucede especialmente cuando hablamos de una plataforma que en el pasado se desplegaba en cualquier plataforma que estaba poblada con información como el nombre de la aplicación, versión, dominio, etc. Pero esto es complicado en un enfoque nativo de la nube. O tal vez no, pero al menos por algún tiempo, te has estado preguntando cómo puedes acceder a parte de la información que conoces sobre tu carga de trabajo nativa de la nube, para que la aplicación en ejecución dentro del pod también la conozca.

Porque cuando defines un nativo de la nube, describes mucha información muy relevante. Por ejemplo, pensemos en eso. Cuando inicias tu pod, conoces el nombre de tu pod porque es tu nombre de host:

Metadatos de Kubernetes: Potencia tus aplicaciones con contenido de tus pods

Pero cuando defines tu carga de trabajo, tienes un nombre de despliegue; ¿cómo puedes obtenerlo desde tu pod? ¿Cómo obtienes en qué espacio de nombres se ha desplegado tu pod? ¿O qué hay de toda la metadata que definimos como etiquetas y anotaciones?

Lo bueno es que hay una manera de obtener cada dato que hemos comentado, así que no te preocupes; obtendrás toda esta información disponible para usar si la necesitas.

La forma estándar de acceder a cualquier información es a través de variables de entorno. Esta es la forma tradicional en que proporcionamos datos iniciales a nuestro pod. Ya hemos visto que sabemos que podemos usar ConfigMaps para poblar variables de entorno, pero esta no es la única manera de proporcionar datos a nuestros pods. Hay mucho más, así que échale un vistazo.

Descubriendo la opción fieldRef

Cuando discutimos el uso de ConfigMap como variables de entorno, teníamos dos maneras de poblar esa información. Proporcionando todo el contenido de ConfigMap, en cuyo caso usamos la opción envFrom, también podemos usar valueFrom y proporcionar el nombre del configMap y la misma clave de la que nos gustaría obtener el valueFrom.

Así que, siguiendo el enfoque de esta sección, tenemos un comando aún más útil llamado fieldRef. fieldRef es el nombre del comando para una referencia a un campo, y podemos usarlo dentro de la directiva valueFrom. En resumen, podemos proporcionar una referencia de campo como un valor para una clave de variable de entorno.

Así que echemos un vistazo a los datos que podemos obtener de este objeto:

  • metadata.name: Esto obtiene el nombre del pod como un valor para un valor de entorno
  • metadata.namespace: Proporciona el espacio de nombres en el que el pod está ejecutándose como el valor
  • metadata.labels[LABELNAME]: Extrae el valor de la etiqueta como el valor para la clave de entorno
  • metadata.annotations[ANNOTATIONNAME]: Extrae el valor de la anotación como valor para la clave de entorno

Aquí puedes ver un fragmento que define diferentes variables de entorno usando esta metadata como el valor para que puedas usarlo dentro del pod simplemente recopilándolo como variables de entorno estándar:

        env:
        - name: APP_NAME
          valueFrom:
            fieldRef:
              fieldPath: metadata.labels['app']
        - name: DOMAIN_NAME
          valueFrom:
            fieldRef:
              fieldPath: metadata.labels['domain']
        - name: POD_NAMESPACE
          valueFrom:
            fieldRef:
              fieldPath: metadata.namespace
        - name: POD_NAME
          valueFrom:
            fieldRef:
              fieldPath: metadata.name 

Yendo aún más allá

Pero esto no es todo lo que la opción fieldRef puede proporcionar, hay mucho más, y si te gustaría echar un vistazo, puedes hacerlo 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.

Descubriendo la Verdad Detrás de los Secretos de Kubernetes

man in white dress shirt wearing black framed eyeglasses
Descubriendo la Verdad Detrás de los Secretos de Kubernetes

Foto por krakenimages en Unsplash

Hemos estado hablando recientemente sobre ConfigMap como uno de los objetos para almacenar una configuración diferente para cargas de trabajo basadas en Kubernetes. Pero, ¿qué pasa con los datos sensibles?

Esta es una pregunta interesante, y la respuesta inicial de la plataforma Kubernetes fue proporcionar un objeto Secrets. Basado en su definición del sitio web oficial de Kubernetes, definen los secretos de esta manera:

Un Secret es un objeto que contiene una pequeña cantidad de datos sensibles como una contraseña, un token o una clave. Tal información podría de otro modo ser puesta en una especificación de Pod o en una imagen de contenedor. Usar un Secret significa que no necesitas incluir datos confidenciales en el código de tu aplicación

Entonces, por defecto, los secretos son lo que deberías usar para almacenar tus datos sensibles. Desde la perspectiva técnica, para usarlos, se comportan de manera muy similar a ConfigMap, por lo que puedes vincularlo a las diferentes variables de entorno, montarlo dentro de un pod, o incluso tener usos específicos para gestionar credenciales para diferentes tipos de cuentas como Cuentas de Servicio. Esto clasifica los diferentes tipos de secretos que puedes crear:

  • Opaco: Esto define un secreto genérico que puedes usar para cualquier propósito (principalmente datos de configuración o archivos de configuración)
  • Token de Cuenta de Servicio: Esto define las credenciales para cuentas de servicio, pero esto está obsoleto y ya no se usa desde Kubernetes 1.22.
  • Credenciales de Registro Docker: Esto define credenciales para conectarse al registro Docker para descargar imágenes como parte de tu proceso de implementación.
  • Autenticación Básica o SSH: Esto define secretos específicos para manejar la autenticación.
  • Secreto TLS:
  • Secretos de Arranque:

Pero, ¿es seguro usar Kubernetes Secrets para almacenar datos sensibles? La respuesta principal para cualquier pregunta en cualquier tema relacionado con la tecnología es: Depende. Pero ha surgido cierta controversia que este tema también se cubre en la página oficial de Kubernetes, destacando los siguientes aspectos:

Los Secrets de Kubernetes se almacenan, por defecto, sin cifrar en el almacén de datos subyacente del servidor API (etcd). Cualquiera con acceso a la API puede recuperar o modificar un Secret, y también cualquiera con acceso a etcd. Además, cualquiera que esté autorizado para crear un Pod en un espacio de nombres puede usar ese acceso para leer cualquier Secret en ese espacio de nombres; esto incluye acceso indirecto como la capacidad de crear un Deployment.

Entonces, lo principal es que, por defecto, esta es una forma muy, muy insegura. Parece más una categorización de los datos que un manejo seguro adecuado. Además, Kubernetes proporciona algunos consejos para intentar hacer esta alternativa más segura:

  • Habilitar el Cifrado en Reposo para los Secrets.
  • Habilitar o configurar reglas RBAC que restrinjan la lectura de datos en los Secrets (incluyendo medios indirectos).
  • Cuando sea apropiado, también usar mecanismos como RBAC para limitar qué principales tienen permitido crear nuevos Secrets o reemplazar los existentes.

Pero eso puede no ser suficiente, y eso ha creado espacio para que terceros y proveedores de la nube ofrezcan su solución que cubra estas necesidades y al mismo tiempo también ofrezca características adicionales. Algunas de estas opciones son las que se muestran a continuación:

  • Sistemas de Gestión de Claves en la Nube: Prácticamente todos los grandes proveedores de la nube proporcionan alguna forma de Gestión de Secretos para ir más allá de estas características y mitigar esos riesgos. Si hablamos de AWS, está AWS Secrets Manager , si hablamos de Azure, tenemos Azure Key Vault , y en el caso de Google, también tenemos Google Secret Manager.
  • Sealed Secrets es un proyecto que intenta extender los Secrets para proporcionar más seguridad, especialmente en el enfoque de Configuración como Código, ofrece una forma segura de almacenar esos objetos en el mismo tipo de repositorios que expones cualquier otro archivo de recursos de Kubernetes. En sus propias palabras, “El SealedSecret solo puede ser descifrado por el controlador que se ejecuta en el clúster de destino, y nadie más (ni siquiera el autor original) puede obtener el Secret original del SealedSecret.”
  • Gestores de Secretos de terceros que son similares a los de los Proveedores de la Nube que permiten un enfoque más independiente, y hay varios jugadores aquí como Hashicorp Vault o CyberArk Secret Manager
  • Finalmente también, Spring Cloud Config puede proporcionar seguridad para almacenar datos que están relacionados con conceptos de configuración sensibles como contraseñas y al mismo tiempo cubre la misma necesidad que proporciona ConfigMap desde una perspectiva unificada.

Espero que este artículo haya ayudado a entender el propósito de los Secrets en Kubernetes y, al mismo tiempo, los riesgos respecto a su seguridad y cómo podemos mitigarlos o incluso confiar en otras soluciones que proporcionen una forma más segura de manejar esta pieza crítica de información.

📚 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.

¿Por qué deberías potenciar los ConfigMaps en tus implementaciones de Kubernetes?

black and silver laptop computer beside yellow ceramic mug
computadora portátil negra y plateada al lado de una taza de cerámica amarilla
Foto por Sigmund en Unsplash

ConfigMaps es uno de los objetos más conocidos y, al mismo tiempo, menos utilizados en el ecosistema de Kubernetes. Es uno de los objetos principales que ha estado allí desde el principio, incluso si probamos muchas otras formas de implementar una solución de Gestión de Configuración (como Consul, Spring Cloud Config y otros).

Basado en las palabras de su propia documentación:

Un ConfigMap es un objeto API utilizado para almacenar datos no confidenciales en pares clave-valor.

https://kubernetes.io/docs/concepts/configuration/configmap/

Su motivación fue proporcionar una solución nativa para la gestión de configuraciones para implementaciones nativas de la nube. Una forma de gestionar e implementar configuraciones enfocándose en un código diferente de la configuración. Ahora, todavía recuerdo los archivos WAR con el archivo application.properties dentro de él.

ConfigMap es un recurso tan simple como puedes ver en el fragmento a continuación:

apiVersion: v1
kind: ConfigMap
metadata:
  name: game-demo
data:
  player_initial_lives: "3"
  ui_properties_file_name: "user-interface.properties"

Los ConfigMaps son objetos que pertenecen a un namespace. Tienen una fuerte relación con Deployment y Pod y permiten la opción de tener diferentes entornos lógicos usando namespace donde pueden implementar la misma aplicación. Aún así, con una configuración específica, por lo que necesitarán un configMap particular para soportar eso, incluso si se basa en el mismo archivo YAML de recursos.

Desde una perspectiva técnica, el contenido del ConfigMap se almacena en la base de datos etcd como sucede con cualquier información relacionada con el entorno de Kubernetes, y debes recordar que etcd por defecto no está cifrado, por lo que todos los datos pueden ser recuperados por cualquiera que tenga acceso a él.

Propósitos de los ConfigMaps

Parámetros de Configuración

El primer y principal propósito del configMap es proporcionar parámetros de configuración a tu carga de trabajo. Una forma industrializada de eliminar la necesidad de variables de entorno es vincular la configuración del entorno desde tu aplicación.

¿Por qué deberías potenciar los ConfigMaps en tus implementaciones de Kubernetes?

Proporcionar Archivos Dependientes del Entorno

Otro uso significativo es proporcionar o reemplazar archivos dentro de tus contenedores que contengan el archivo de configuración crítica. Uno de los ejemplos principales que ilustra esto es proporcionar una configuración de registro para tu aplicación si tu aplicación está utilizando la biblioteca logback. En este caso, necesitas proporcionar un archivo logback.xml, para que sepa cómo aplicar tu configuración de registro.

Otras opciones pueden ser propiedades. El archivo necesita estar ubicado allí o incluso certificados de clave pública para manejar conexiones SSL solo con servidores en lista segura.

¿Por qué deberías potenciar los ConfigMaps en tus implementaciones de Kubernetes?
¿Por qué deberías potenciar los ConfigMaps en tus implementaciones de Kubernetes?

Carpetas de Solo Lectura

Otra opción es usar el ConfigMap como una carpeta de solo lectura para proporcionar una forma inmutable de vincular información al contenedor. Un caso de uso de esto puede ser los Dashboards de Grafana que estás agregando a tu pod de Grafana (si no estás usando el operador de Grafana)

¿Por qué deberías potenciar los ConfigMaps en tus implementaciones de Kubernetes?

Diferentes formas de crear un ConfigMap

Tienes varias formas de crear un ConfigMap usando el modo interactivo que simplifica su creación. Aquí están las que más uso:

Crear un configMap para alojar pares clave-valor con fines de configuración

kubectl create configMap name  --from-literal=key=value

Crear un configMap usando un archivo de propiedades similar a Java para poblar el ConfigMap en un par clave-valor.

 kubectl create configMap name --from-env-file=filepath

Crear un configMap usando un archivo para ser parte del contenido del ConfigMap

 kubectl create configMap name --from-file=filepath

 Ciclo de Vida de Actualización del ConfigMap

Los ConfigMaps se actualizan de la misma manera que cualquier otro objeto de Kubernetes, y puedes usar incluso los mismos comandos como kubctl apply para hacerlo. Pero debes tener cuidado porque una cosa es actualizar el ConfigMap en sí y otra cosa es que el recurso que usa este ConfigMap se actualice.

En todos los casos de uso que hemos descrito aquí, el contenido del ConfigMap depende del ciclo de vida del Pod. Eso significa que el contenido del ConfigMap se lee en el proceso de inicialización del Pod. Por lo tanto, para actualizar los datos del ConfigMap dentro del pod, necesitarás reiniciar o traer una nueva instancia del pod después de haber modificado el objeto ConfigMap en sí.

📚 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 mejorar tus posibilidades de dominar tu examen de certificación de Kubernetes (CKAD)?

person writing on white paper

Aprende de mi propia experiencia para aprobar tu examen de certificación de Kubernetes

persona escribiendo en papel blanco
Foto de Nguyen Dang Hoang Nhu en Unsplash

Pero también me gustaría proporcionar algunos consejos prácticos basados en mi propia experiencia si esto puede ayudar a alguien más que esté pasando por el mismo proceso. Sé que hay muchos artículos similares, y la mayoría de ellos valen la pena porque cada uno proporciona una perspectiva y enfoque diferente. Así que aquí está el mío:

  • Rápido pero seguro. Tendrás alrededor de 2 horas para completar entre 15 a 20 preguntas prácticas, lo que te da aproximadamente 6 minutos cada una en promedio. Es tiempo suficiente para hacerlo, pero también debes ir rápido. Así que, trata de evitar el enfoque de leer todo el examen primero o moverte entre preguntas. Es mejor comenzar con la primera de inmediato y si te bloqueas, pasa a la siguiente. Al mismo tiempo, debes validar el resultado que estás obteniendo para asegurarte de que no te estás perdiendo nada. Intenta ejecutar cualquier comando para validar si los objetos se han creado correctamente y tienen los atributos y configuración correctos antes de pasar al siguiente. El tiempo es precioso. Tuve mucho tiempo al final del examen para revisar las preguntas, pero también es cierto que pasé 20 minutos porque escribí ngnix en lugar de nginx, ¡y no pude verlo!
  • Los comandos imperativos son el camino a seguir: Debes aprender la estructura YAML para los objetos principales. Deployment, Pod, CronJob, Jobs, etc. También necesitarás dominar los comandos imperativos para generar el resultado inicial rápidamente. Comandos imperativos como kubectl run, kubectl create, kubectl expose no proporcionarán el 100% de la respuesta, pero tal vez el 80% es la base para hacer arreglos y tener la solución a tu pregunta rápidamente. Recomiendo echar un vistazo a este recurso:
  • kubectl explain para evitar pasar por la documentación o pensar mucho. Tengo un problema para aprender el nombre exacto de un campo o la ubicación en el archivo YAML. Así que usé mucho el kubectl explain, especialmente con la bandera —rescursive. Proporciona la estructura YAML, así que, si no recuerdas si el nombre de la clave es configMap o ConfigMapRef o claimName o persitentVolumeClaim, esto será de gran ayuda. Si también agregas un comando grep -A 10 -B 5 para encontrar tu campo y su contexto, lo dominarás. Esto no reemplaza conocer la estructura YAML, pero ayudará a ser eficiente cuando no recuerdes el nombre exacto o la ubicación.
¿Cómo mejorar tus posibilidades de dominar tu examen de certificación de Kubernetes (CKAD)?
kubectl explain pod –recursive
  • No te olvides de docker/podman y helm: Con los cambios en la certificación en septiembre de 2021, también el proceso de construcción es esencial, por lo que es excelente si tienes suficiente tiempo en tu preparación para jugar con herramientas como docker/podman o helm para que domines cualquier pregunta relacionada con eso que puedas encontrar.
  • Usa el simulador: LinuxFoundation te proporciona dos sesiones en el simulador que, por un lado, te darán una experiencia de examen auténtica, para que enfrentes tipos de preguntas e interfaz similares y sientas que no es la primera vez que te enfrentas y al mismo tiempo podrías sentirte familiarizado con el entorno. Recomiendo usar ambas sesiones (ambas tienen la misma pregunta), una en medio de tu entrenamiento y la segunda uno o dos días antes de tu examen.

Así que, aquí están mis consejos, y espero que te gusten. Si te fueron útiles, por favor házmelo saber en redes sociales o por correo o cualquier otra forma de contacto que prefieras. ¡Todo lo mejor en tu preparación, y estoy seguro de que alcanzarás tus metas!

📚 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.

Mi opinión sobre la certificación de Kubernetes (CKAD)

girl in black t-shirt writing on white paper

Mi Experiencia y Sentimientos Después de Aprobar el Desarrollador de Aplicaciones Certificado de Kubernetes

chica con camiseta negra escribiendo en papel blanco
Foto por Jeswin Thomas en Unsplash

La semana pasada aprobé la certificación de Desarrollador de Aplicaciones Certificado de Kubernetes (CKAD) con una puntuación de 95/100, y fue más difícil de lo que parece, aunque esta es la más fácil de las certificaciones de Kubernetes, la forma en que está diseñado el examen y las habilidades que se evalúan en él te hacen dudar de tu conocimiento.

He estado usando Kubernetes diariamente durante más de tres años. Debido a mi trabajo, es necesario implementar, definir, solucionar problemas de cargas de trabajo basadas en Kubernetes en diferentes plataformas (Openshift, EKS, AKS… cualquier cosa), por lo que podrías pensar que no debería necesitar prepararme para este tipo de examen, y esa podría ser también la impresión. Pero esto está lejos de la realidad.

Siento que no hay ninguna certificación que puedas aprobar sin preparación porque la certificación no mide cuán hábil eres en ningún otro tema que no sea el proceso de certificación en sí. Puedes ser el maestro de cualquier tecnología, pero si vas a un examen de certificación sin ninguna preparación específica para el examen, tienes muchas posibilidades de fallar.

Incluso en este caso en que hemos pasado de la tradicional pregunta de caso teórico a una más práctica, no es diferente. Porque sí, no necesitas aprender nada, y sí, requiere que realmente puedas hacer cosas, no solo saber sobre algo, pero todo lo demás es igual.

Te preguntarán sobre cosas que nunca usarás en la vida real, necesitarás usar comandos que solo vas a usar en el examen, y necesitarás hacerlo de la manera específica que se espera también porque así es como funciona la certificación. ¿Es malo? Probablemente… ¿hay alguna otra forma de hacerlo? No hemos encontrado aún ninguna mejor.

Debo admitir que creo que este proceso es mucho más justo que el de caso de prueba, aunque prefiero el caso de prueba solo por una cuestión de tiempo durante el proceso.

Entonces, probablemente, te estás preguntando si esa es mi opinión, ¿por qué intento aprobar la certificación en primer lugar? Hay varias razones para hacerlo. En primer lugar, creo que la certificación es una gran manera de establecer un estándar de conocimiento para cualquiera. Eso no significa que las personas con la certificación sean más competentes o mejor capacitadas que las personas sin la certificación. No me considero más calificado hoy que hace un mes cuando comencé a prepararme para la certificación, pero al menos estableció alguna base de lo que puedes esperar.

Además de eso, es un desafío para ti mismo, para mostrarte que puedes hacerlo, y siempre es genial empujar tus límites un poco más allá de lo que es obligatorio para el trabajo. Y finalmente, es algo que se ve bien en tu CV, eso es seguro.

¿Aprendí algo nuevo? Sí, por supuesto, muchas cosas. Incluso me mejoré a mí mismo porque usualmente hago algunas tareas, y solo eso ya valió la pena. Incluso si fallara, creo que valió la pena porque siempre te da algo más para agregar a tu cadena de herramientas, y eso siempre es bueno.

Además, este examen no asegura que seas un buen Desarrollador de Aplicaciones de Kubernetes. En mi opinión, creo que el enfoque del examen está centrado en mostrar que eres un Implementador de Kubernetes justo. ¿Por qué digo eso? Vamos a añadir algunos puntos:

  • No obtienes ningún punto por proporcionar la mejor solución para un problema. La pregunta es tan específica que se trata de traducir lo que está escrito en inglés simple a acciones y objetos de Kubernetes.
  • Hay preguntas de solución de problemas, sí, pero también hay algunas bastante básicas que no aseguran que tu proceso de pensamiento sea eficiente. Nuevamente, la eficiencia no se evalúa en el proceso.

Entonces, probablemente estoy echando de menos un examen de Arquitectura Certificada de Kubernetes donde puedas tener la definición de un problema, y necesitas proporcionar una solución. Serás evaluado en base a eso. Incluso con alguna forma de justificar la decisión que estás tomando y el proceso de pensamiento, no creo que alguna vez veamos eso. ¿Por qué? Porque, y eso es muy importante porque cualquier nuevo examen de certificación que enfrentemos necesita ser lo suficientemente específico para que pueda ser evaluado automáticamente.

📚 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.

De Docker Desktop a Rancher Desktop: Rápido y Sencillo

De Docker Desktop a Rancher Desktop: Rápido y Sencillo
contenedores intermodales archivados de varios colores
Foto de frank mckenna en Unsplash

Como la mayoría de ustedes ya saben, el 31 de enero es el último día para usar Docker Desktop sin aplicar el nuevo modelo de licencias que prácticamente genera un costo para cualquier uso empresarial. Por supuesto, todavía es gratuito para usar en proyectos de código abierto y pequeñas empresas, pero es mejor cumplir con los requisitos utilizando la documentación oficial de Docker.

Actualización: OrbStack vs Docker Desktop, Rancher Desktop y Colima (actualización 2026).

Así que debido a esa situación, comencé un viaje para encontrar una alternativa a Docker Desktop porque usaba mucho docker-desktop. El uso principal que hago es iniciar cosas similares a servidores para uso temporal que no me gusta tener instaladas en mi máquina para mantenerla lo más limpia posible (aunque esto no siempre es cierto, pero es un intento).

Entonces, en esa búsqueda, descubrí que Rancher Desktop fue lanzado no hace mucho tiempo y prometía ser la alternativa más adecuada. El objetivo de este post no es comparar ambas plataformas, pero si deseas tener más información, dejo aquí un post que puede proporcionártela:

La idea aquí es hablar más sobre el viaje de esa migración. Así que instalé Rancher Desktop 1.0.0 en mi Mac y la instalación fue muy, muy fácil. La principal diferencia con Docker Desktop es que Rancher Desktop está construido pensando en Kubernetes y para Docker Desktop, eso vino como una idea posterior. Así que, por defecto, tendremos un entorno de Kubernetes ejecutándose en nuestro sistema, y podemos incluso seleccionar la versión de ese clúster como puedes ver en la imagen a continuación:

Pero también en Rancher, notaron la ventana de oportunidad que tienen frente a ellos, y fueron muy agresivos al proporcionar un camino de migración fácil desde Docker Desktop. Y lo primero que notarás es que puedes configurar Docker Desktop para que sea compatible con la API de Docker CLI como puedes ver en la imagen a continuación.

Esto no está habilitado por defecto, pero es muy fácil hacerlo y te permitirá no tener que cambiar todos tus comandos “similares a docker” (docker build, docker ps.. ) por lo que suavizará mucho la transición.

Quizás en el futuro, quieras alejarte de todo lo que se asemeje a docker incluso en el lado del cliente y moverte a un enfoque tipo Containers, pero por ahora, lo que necesitaba es simplificar el proceso.

Así que, después de habilitar eso y reiniciar mi Rancher Desktop, puedo escribir mis comandos como puedes ver en la imagen a continuación:

Así que, lo único que necesito hacer es migrar mis imágenes y contenedores. Porque no soy un usuario puro de docker, a veces no sigo la idea de tener tu contenedor sin estado y usar volúmenes especialmente cuando estás haciendo un uso pequeño por algún tiempo y eso es todo. Así que, eso significa que algunos de mis contenedores también necesitan ser movidos a la nueva plataforma para evitar cualquier pérdida de datos.

Así que, mi viaje de migración tuvo diferentes pasos:

  • En primer lugar, voy a comprometer los contenedores con estado que necesito mantener en el nuevo sistema usando el comando docker commit con la documentación que puedes encontrar aquí:
  • Luego, exportaré todas las imágenes que tengo ahora en archivos TAR usando el comando docker save con la documentación que puedes encontrar aquí:
  • Y finalmente, cargaré todas esas imágenes en el nuevo sistema usando el comando docker load para tenerlas disponibles allí. Nuevamente, puedes encontrar la documentación de ese comando específico aquí

Para automatizar un poco el proceso, incluso que no tengo muchas imágenes cargadas porque trato de limpiar de vez en cuando usando el comando docker system prune:

Prefiero no hacerlo manualmente, así que usaré algunos scripts simples para hacer el trabajo.

Así que, para realizar el trabajo de exportación, necesito ejecutar el siguiente comando:

docker image ls -q | xargs -I {} docker image save {} -o {}.tar

Este script guardará todas mis imágenes en diferentes archivos tar en una carpeta específica. Ahora, solo necesito ejecutar el siguiente comando desde la misma carpeta en la que ejecuté el anterior para tener todas las imágenes de vuelta en el nuevo sistema:

find . -name "*.tar" -exec docker load -i {} ;

La razón por la que no estoy haciendo ambas acciones al mismo tiempo es que necesito tener Docker Desktop ejecutándose para la primera parte y Rancher Desktop para la otra. Así que, aunque puedo automatizar eso también, creo que no vale la pena.

Y eso es todo, ahora puedo eliminar Docker Desktop de mi portátil, y mi vida continuará siendo la misma. Intentaré proporcionar más comentarios sobre cómo se siente, especialmente en cuanto a la utilización de recursos y temas similares en un futuro cercano.

📚 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.