Las 3 mejores opciones para implementar Loki escalable en Kubernetes

Las 3 mejores opciones para implementar Loki escalable en Kubernetes

Modelos de Despliegue para una Arquitectura Escalable de Agregación de Logs usando Loki

Desplegar un Loki escalable no es una tarea sencilla. Ya hemos hablado sobre Loki en publicaciones anteriores en el sitio, y se está volviendo cada vez más popular, y su uso se vuelve mucho más regular cada día. Es por eso que creo que tiene sentido incluir otra publicación sobre la Arquitectura de Loki.

Loki tiene varias ventajas que lo promueven como una opción predeterminada para desplegar una Pila de Agregación de Logs. Una de ellas es su escalabilidad porque puedes ver a través de diferentes modelos de despliegue cuántos componentes te gustaría desplegar y sus responsabilidades. Así que el objetivo del tema es mostrarte cómo desplegar una solución escalable de Loki y esto se basa en dos conceptos: componentes disponibles y cómo los agrupas.

Así que comenzaremos con los diferentes componentes:

  • ingester: responsable de escribir datos de logs en backends de almacenamiento a largo plazo (DynamoDB, S3, Cassandra, etc.) en la ruta de escritura y devolver datos de logs para consultas en memoria en la ruta de lectura.
  • distributor: responsable de manejar flujos entrantes por parte de los clientes. Es el primer paso en la ruta de escritura para los datos de logs.
  • query-frontend: servicio opcional que proporciona los puntos finales de la API del querier y puede usarse para acelerar la ruta de lectura.
  • querier: servicio que maneja consultas usando el lenguaje de consulta LogQL, obteniendo logs de los ingesters y del almacenamiento a largo plazo.
  • ruler: responsable de evaluar continuamente un conjunto de consultas configurables y realizar una acción basada en el resultado.

Luego puedes unirlos en diferentes grupos, y dependiendo del tamaño de estos grupos, tienes una topología de despliegue diferente, como se muestra a continuación:

Las 3 mejores opciones para implementar Loki escalable en Kubernetes
Modo de Despliegue Monolítico de Loki
  • Monolito: Como puedes imaginar, todos los componentes se ejecutan juntos en una sola instancia. Esta es la opción más simple y se recomienda como un punto de partida de 100 GB / día. Incluso puedes escalar este despliegue, pero escalará todos los componentes simultáneamente, y debería tener un estado de objeto compartido.
Las 3 mejores opciones para implementar Loki escalable en Kubernetes
Modo de Despliegue Escalable Simple de Loki
  • Modelo de Despliegue Escalable Simple: Este es el segundo nivel, y puede escalar hasta varios TB de logs por día. Consiste en dividir los componentes en dos perfiles diferentes: lectura y escritura.
Las 3 mejores opciones para implementar Loki escalable en Kubernetes
Modo de Despliegue de Microservicios de Loki
  • Microservicios: Eso significa que cada componente será gestionado de manera independiente, dándote todo el poder en tus manos para escalar cada uno de estos componentes por separado.

Definir el modelo de despliegue de cada instancia es muy fácil, y se basa en un solo parámetro llamado target. Así que dependiendo del valor del target seguirá uno de los modelos de despliegue anteriores:

  • all (por defecto): Se desplegará en modo monolítico.
  • write: Será la ruta de escritura en el modelo de despliegue escalable simple
  • read: Será el grupo de lectura en el modelo de despliegue escalable simple
  • ingester, distributor, query-frontend, query-scheduler, querier, index-gateway, ruler, compactor: Valores individuales para desplegar un solo componente para el modelo de despliegue de microservicios.

El argumento target ayudará para un tipo de despliegue on-premises. Aún así, si estás usando Helm para la instalación, Loki ya proporciona diferentes charts de helm para los otros modelos de despliegue:

Pero todos esos charts de helm se basan en el mismo principio comentado anteriormente sobre definir el rol de cada instancia usando el argumento target, como puedes ver en la imagen a continuación:

Las 3 mejores opciones para implementar Loki escalable en Kubernetes

📚 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 habilitar los registros de acceso en las rutas predeterminadas de Openshift

white and gray spiral stairs

Pon algo de cerebro cuando una ruta no funciona como se espera, o tus consumidores no pueden acceder al servicio

Todos sabemos que Openshift es una distribución de Kubernetes excepcional y una de las más utilizadas, principalmente cuando se habla de implementaciones en la nube privada. Basado en la sólida reputación de Red Hat Enterprise Linux, Openshift pudo crear un producto sólido que se está convirtiendo casi en un estándar para la mayoría de las empresas.

Proporciona muchas extensiones del estilo de Kubernetes Vanilla, incluyendo algunos de los estándares de la industria de código abierto como Prometheus, Thanos y Grafana para el monitoreo de métricas o la pila ELK para la agregación de registros, pero también incluye sus extensiones como las Rutas de Openshift.

Las Rutas de Openshift fueron la solución inicial antes de que el concepto de Ingress fuera una realidad dentro del estándar. Ahora, también se implementa siguiendo ese patrón para mantener la compatibilidad. Está respaldado por HAProxy, uno de los proxies inversos más conocidos disponibles en la comunidad de código abierto.

Una de las partes complicadas por defecto es saber cómo depurar cuando una de tus rutas no funciona como se espera. La forma en que creas rutas es tan fácil que cualquiera puede hacerlo en unos pocos clics, y si todo funciona como se espera, eso es genial.

Pero si no es así, los problemas comienzan porque, por defecto, no obtienes ningún registro sobre lo que está sucediendo. Pero eso es lo que vamos a resolver aquí.

Primero, hablaremos un poco más sobre cómo se configura esto. Actualmente (versión 4.8 de Openshift), esto se implementa, como dije, usando HAProxy por defecto, así que si estás usando otra tecnología como ingresses como Istio o Nginx, este artículo no es para ti (pero no olvides dejar un comentario si un artículo similar sería de tu interés para que también pueda llevarlo al backlog 🙂 )

Desde la perspectiva de la implementación, esto se implementa usando el Marco de Operadores, por lo que el ingreso se despliega como un Operador, y está disponible en el espacio de nombres openshift-ingress-operator.

Cómo habilitar los registros de acceso en las rutas predeterminadas de Openshift
pods del operador de ingreso en el ecosistema de Openshift

Entonces, como esto es un operador, se han instalado varias Definiciones de Recursos Personalizados (CRD) para trabajar con esto, una de las más interesantes de este artículo. Este CRD es Controladores de Ingreso.

Cómo habilitar los registros de acceso en las rutas predeterminadas de Openshift
Instancias de Ingreso en el Ecosistema de Openshift

Por defecto, solo verás una instancia llamada default. Esta es la que incluye la configuración del ingreso que se está desplegando, por lo que necesitamos agregar aquí una configuración adicional para tener también los registros.

Cómo habilitar los registros de acceso en las rutas predeterminadas de Openshift
Archivo YAML del controlador de ingreso

El fragmento que necesitamos es el que se muestra a continuación bajo el parámetro spec que comienza la definición de la especificación del IngressController en sí:

   logging:
    access:
      destination:
        type: Container
      httpLogFormat: >-
        log_source="haproxy-default" log_type="http" c_ip="%ci" c_port="%cp"
        req_date="%tr" fe_name_transport="%ft" be_name="%b" server_name="%s"
        res_time="%TR" tot_wait_q="%Tw" Tc="%Tc" Tr="%Tr" Ta="%Ta"
        status_code="%ST" bytes_read="%B" bytes_uploaded="%U"
        captrd_req_cookie="%CC" captrd_res_cookie="%CS" term_state="%tsc"
        actconn="%ac" feconn="%fc" beconn="%bc" srv_conn="%sc" retries="%rc"
        srv_queue="%sq" backend_queue="%bq" captrd_req_headers="%hr"
        captrd_res_headers="%hs" http_request="%r"
 

Esto hará que se despliegue otro contenedor en los pods del enrutador en el espacio de nombres openshift-ingress siguiendo el patrón sidecar llamado logs.

Cómo habilitar los registros de acceso en las rutas predeterminadas de Openshift
Pods del enrutador en la instalación de Openshift

Este contenedor imprimirá los registros de las solicitudes que llegan al componente de ingreso, por lo que la próxima vez que tu consumidor no pueda llamar a tu servicio, podrás ver las solicitudes entrantes con todos sus metadatos y saber al menos qué está haciendo mal:

Cómo habilitar los registros de acceso en las rutas predeterminadas de Openshift
Registros de acceso de la Ruta de Openshift

Como puedes ver, ¡simple y fácil! Si ya no lo necesitas, puedes eliminar la configuración nuevamente y guardarla, y la nueva versión se implementará y volverá a la normalidad.

📚 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 la productividad en el desarrollo de cargas de trabajo de Kubernetes

timelapse photo of highway during golden hour

La telepresencia es la forma de reducir el tiempo entre tus líneas de código y una carga de trabajo nativa de la nube en ejecución.

foto de lapso de tiempo de la autopista durante la hora dorada
Foto de Joey Kyber en Unsplash

Todos sabemos cómo las cargas de trabajo nativas de la nube y Kubernetes han cambiado la forma en que hacemos las cosas. Hay muchos beneficios que vienen con el efecto de la contenedorización y las plataformas de orquestación como Kubernetes, y hemos discutido mucho sobre ello: escalabilidad, autocuración, autodescubrimiento, resiliencia, y así sucesivamente.

Pero se han planteado algunos desafíos, la mayoría de ellos en el aspecto operativo en el que tenemos muchos proyectos enfocados en abordar, pero generalmente olvidamos lo que el embajador ha definido como el “ciclo de desarrollo interno”.

El “ciclo de desarrollo interno” es el flujo de trabajo productivo que cada desarrollador sigue al trabajar en una nueva aplicación, servicio o componente. Este flujo iterativo es donde codificamos, probamos lo que hemos codificado y arreglamos lo que no funciona o mejoramos lo que ya tenemos.

Este flujo ha existido desde el principio de los tiempos; no importa si estabas codificando en C usando la biblioteca STD o COBOL a principios de 1980 o haciendo nodejs con los últimos marcos y bibliotecas a tu disposición.

Hemos visto movimientos hacia hacer este ciclo interno más efectivo, especialmente en el desarrollo front-end. Tenemos muchas opciones para ver el último cambio que hemos hecho en el código, solo guardando el archivo. Pero por primera vez, cuando el movimiento hacia una plataforma basada en contenedores, este flujo hace que los desarrolladores sean menos productivos.

La razón principal es que el número de tareas que un desarrollador necesita hacer ha aumentado. Imagina este conjunto de pasos que necesitamos realizar:

  • Construir la aplicación
  • Construir la imagen del contenedor
  • Desplegar la imagen del contenedor en Kubernetes

Estas acciones no son tan rápidas como probar tus cambios localmente, haciendo que los desarrolladores sean menos productivos que antes, que es lo que el proyecto “telepresencia” está tratando de resolver.

La telepresencia es un proyecto incubador de la CNCF que ha centrado mucha atención recientemente porque se ha incluido OOTB en las últimas versiones del componente Docker Desktop. Basado en sus propias palabras, esta es la definición del proyecto de telepresencia:

La telepresencia es una herramienta de código abierto que permite a los desarrolladores codificar y probar microservicios localmente contra un clúster de Kubernetes remoto. La telepresencia facilita flujos de trabajo de desarrollo más eficientes aliviando la necesidad de preocuparse por otras dependencias de servicio.

Ok, entonces, ¿cómo podemos empezar? Vamos a sumergirnos juntos. Lo primero que necesitamos hacer es instalar la telepresencia en nuestro clúster de Kubernetes:

Nota: También hay una forma de instalar telepresencia usando Helm en tu clúster siguiendo estos pasos:

helm repo add datawire  https://app.getambassador.io
helm repo update
kubectl create namespace ambassador
helm install traffic-manager --namespace ambassador datawire/telepresence

Ahora crearé un contenedor simple que alojará una aplicación Golang que expone un servicio REST simple y lo haré más accesible; seguiré el tutorial que está disponible a continuación; tú también puedes hacerlo.

Una vez que tengamos nuestra aplicación golang lista, vamos a generar el contenedor a partir de ella, usando el siguiente Dockerfile:

FROM golang:latest

RUN apt-get update
RUN apt-get upgrade -y

ENV GOBIN /go/bin

WORKDIR /app

COPY *.go ./
RUN go env -w GO111MODULE=off
RUN go get .
RUN go build -o /go-rest
EXPOSE 8080
CMD [ "/go-rest" ]

Luego, una vez que tengamos la aplicación, la subiremos al servidor de Kubernetes y la ejecutaremos como un despliegue, como puedes ver en la imagen a continuación:

kubectl create deployment rest-service --image=quay.io/alexandrev/go-test  --port=8080
kubectl expose deploy/rest-service

Una vez que tengamos eso, es el momento de comenzar a ejecutar la telepresencia, y comenzaremos a conectarnos al clúster usando el siguiente comando telepresence connect, y mostrará una salida como esta:

Cómo mejorar la productividad en el desarrollo de cargas de trabajo de Kubernetes

Luego vamos a listar los puntos finales disponibles para interceptar con el comando telepresence list y veremos nuestro servicio-rest que hemos expuesto antes:

Cómo mejorar la productividad en el desarrollo de cargas de trabajo de Kubernetes

Ahora, ejecutaremos el interceptor específico, pero antes de eso, vamos a hacer el truco para que podamos conectarlo a nuestro Visual Studio Code. Generaremos un archivo launch.json en Visual Studio Code con el siguiente contenido:

{
    // Usa IntelliSense para aprender sobre posibles atributos.
    // Pasa el ratón para ver descripciones de atributos existentes.
    // Para más información, visita: https://go.microsoft.com/fwlink/?linkid=830387
    "version": "0.2.0",
    "configurations": [
        {
            "name": "Lanzar con archivo env",
            "type": "go",
            "request": "launch",
            "mode": "debug",
            "program": "1",
            "envFile": "NULL/go-debug.env"
           }
    ]
}

La parte interesante aquí es el argumento envFile que apunta a un archivo inexistente go-debug.env en la misma carpeta, por lo que necesitamos asegurarnos de que generamos ese archivo cuando hacemos la intercepción. Así que usaremos el siguiente comando:

telepresence intercept rest-service --port 8080:8080 --env-file /Users/avazquez/Data/Projects/GitHub/rest-golang/go-debug.env

Y ahora, podemos comenzar nuestra sesión de depuración en Visual Studio Code y tal vez agregar un punto de interrupción y algunas líneas, como puedes ver en la imagen a continuación:

Cómo mejorar la productividad en el desarrollo de cargas de trabajo de Kubernetes

Entonces, ahora, si golpeamos el pod en Kubernetes, veremos cómo se alcanza el punto de interrupción como si estuviéramos en una sesión de depuración local.

Cómo mejorar la productividad en el desarrollo de cargas de trabajo de Kubernetes

Eso significa que podemos inspeccionar variables y todo, cambiar el código o hacer lo que necesitemos para acelerar nuestro desarrollo!

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

ServiceMonitor y PodMonitor de Prometheus: ¡No te pierdas los nuevos conceptos!

black flat screen tv turned on near black and gray audio component

Descubre las diferencias entre dos de los CRDs más utilizados del Operador Prometheus y cómo usar cada uno de ellos.

Conceptos de Prometheus: ServiceMonitor y PodMonitor

Foto de Ibrahim Boran en Unsplash

ServiceMonitor y PodMonitor son términos que comenzarás a ver más a menudo cuando se hable de usar Prometheus. Hemos cubierto mucho sobre Prometheus en artículos anteriores. Es una de las principales referencias cuando hablamos de monitoreo en un entorno nativo de la nube y está especialmente enfocado en el ecosistema de Kubernetes.

Prometheus tiene un nuevo modelo de implementación bajo el Marco del Operador de Kubernetes en tiempos recientes. Eso ha generado varios cambios en términos de recursos y cómo configuramos varios aspectos del monitoreo de nuestras cargas de trabajo. Algunos de estos conceptos ahora se gestionan como Definición de Recurso Personalizado (CRD) que se incluyen para simplificar la configuración del sistema y estar más alineados con las capacidades de la propia plataforma de Kubernetes. Esto es genial pero, al mismo tiempo, cambia cómo necesitamos usar esta excelente herramienta de monitoreo para cargas de trabajo nativas de la nube.

Hoy, cubriremos dos de estos nuevos CRDs, uno de los más relevantes: ServiceMonitor y PodMonitor. Estos son los nuevos objetos que especifican los recursos que estarán bajo el alcance de monitoreo para la plataforma, y cada uno de ellos cubre un tipo diferente de objeto, como puedes imaginar: Servicios y Pods.

Cada uno de ellos tiene su archivo de definición con sus campos y metadatos particulares, y para destacarlos, presentaré un ejemplo para cada uno de ellos a continuación:

Service Monitor

apiVersion: monitoring.coreos.com/v1
kind: ServiceMonitor
metadata:
  labels:
    serviceMonitorSelector: prometheus
  name: prometheus
  namespace: prometheus
spec:
  endpoints:
  - interval: 30s
    targetPort: 9090
    path: /metrics
  namespaceSelector:
    matchNames:
    - prometheus
  selector:
    matchLabels:
      operated-prometheus: "true"

Pod Monitor

apiVersion: monitoring.coreos.com/v1
kind: PodMonitor
metadata:
  name: front-end
  labels:
    name: front-end
spec:
  namespaceSelector:
    matchNames:
      - sock-shop
  selector:
    matchLabels:
      name: front-end
  podMetricsEndpoints:
  - targetPort: 8079

Como puedes ver, las definiciones de los componentes son muy similares y muy intuitivas, enfocándose en el selector para detectar qué pods o servicios debemos monitorear y algunos datos sobre el objetivo específico del monitoreo, para que Prometheus sepa cómo extraerlos.

Si deseas echar un vistazo más en detalle a cualquier opción que puedas configurar en este CRD, te recomendaría que eches un vistazo a esta URL que incluye una documentación detallada campo por campo de los CRDs más comunes:

Estos componentes pertenecerán a la definición de tus cargas de trabajo, lo que significa que la creación y el mantenimiento de estos objetos serán responsabilidad de los desarrolladores de la aplicación.

Eso es genial por varias razones:

  • Incluirá el aspecto de Monitoreo del propio componente, por lo que nunca olvidarás agregar la configuración de un componente específico. Eso significa que se puede incluir en los archivos YAML duplicados o en el Helm Chart o en recursos de Kustomize como otro recurso necesario.
  • Descentralizará la configuración de monitoreo haciéndola más ágil, y progresará a medida que lo hagan los componentes de software.
  • Reducirá el impacto en otros componentes monitoreados ya que no hay necesidad de actuar en ningún archivo o recurso estándar, por lo que cualquier carga de trabajo diferente continuará funcionando como se espera.

Ambos objetos son muy similares en sus propósitos ya que ambos extraen todos los endpoints que coinciden con el selector que agregamos. Entonces, ¿en qué casos debería usar uno u otro?

La respuesta será sencilla. Por defecto, optarás por un ServiceMonitor porque proporcionará las métricas del propio servicio y de cada uno de los endpoints que tiene el servicio, por lo que cada uno de los pods que están implementando el servicio será descubierto y extraído como parte de esta acción.

Entonces, ¿en qué casos debería usar PodMonitor? Donde la carga de trabajo que estás tratando de monitorear no actúa detrás de un servicio, por lo que al no haber un servicio definido, no puedes usar ServiceMonitor. ¿Quieres algunos ejemplos de eso? ¡Traigamos algunos!

  • Servicios que interactúan usando otros protocolos que no son basados en HTTP, como Kafka, SQS/SNS, JMS, o similares.
  • Componentes como CronJobs, DaemonSets, o que no exponen ningún modelo de conexión entrante.

Así que espero que este artículo te ayude a entender la principal diferencia entre esos objetos y profundizar un poco más en cómo funcionan los nuevos recursos del Marco del Operador Prometheus. Continuaremos cubriendo otros aspectos en próximos artículos.

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

Escalar a Cero y Desde Cero en tu Clúster de Kubernetes

brown and beige weighing scale

Llevando la Experiencia Serverless a tu Clúster de Kubernetes

Escalar a Cero y Desde Cero en tu Clúster de Kubernetes

Foto de Piret Ilver en Unsplash

Serverless siempre ha sido considerado el siguiente paso en el viaje a la nube. Sabes a lo que me refiero: comienzas desde tu VM en las instalaciones, luego te mueves a tener contenedores en una plataforma PaaS, y luego intentas encontrar tu próxima parada en este viaje que es serverless.

Escalar a Cero y Desde Cero en tu Clúster de Kubernetes
Evolución tecnológica definida basada en la perspectiva de abstracción de infraestructura

Serverless es la idea de olvidarse de la infraestructura y centrarse solo en tus aplicaciones. No hay necesidad de preocuparse por dónde se ejecutará o la gestión de la infraestructura subyacente. Serverless comenzó como un sinónimo del paradigma de Función como Servicio (FaaS). Fue popularizado primero por las funciones de Amazon Lambda y luego por todos los principales proveedores de nube.

Comenzó como una alternativa al enfoque de contenedores que probablemente requiere muchas habilidades técnicas para gestionar y ejecutar a escala de producción, pero este ya no es el caso.

Hemos visto cómo el enfoque serverless ha llegado a cualquier plataforma a pesar de este punto de partida. Siguiendo los mismos principios, tenemos diferentes plataformas cuyo enfoque es abstraer todos los aspectos técnicos para la parte operativa y proporcionar una plataforma donde puedas poner tu lógica en ejecución. Prácticamente cada plataforma SaaS cubre este enfoque, pero me gustaría destacar algunos ejemplos para aclarar:

  • netlify es una plataforma que te permite desplegar tu aplicación web sin necesidad de gestionar nada más que el código necesario para ejecutarla.
  • TIBCO Cloud Integration es una solución iPaaS que proporciona todos los recursos técnicos que podrías necesitar para que puedas centrarte en desplegar tus servicios de integración.

Pero yendo más allá, prácticamente cada servicio proporcionado por las principales plataformas en la nube como Azure, AWS o GCP sigue el mismo principio. La mayoría de ellos (mensajería, aprendizaje automático, almacenamiento, etc.) abstraen toda la infraestructura subyacente para que puedas centrarte en el servicio real.

Volviendo al ecosistema de Kubernetes, tenemos dos capas diferentes de ese enfoque. La principal es el servicio de Kubernetes gestionado que todas las grandes plataformas proporcionan donde toda la gestión de Kubernetes (nodos maestros, componentes internos de Kubernetes) son transparentes para ti y te centras todo en los trabajadores. Y el segundo nivel es lo que puedes obtener en el mundo de AWS con la arquitectura tipo EKS + Fargate donde ni siquiera existen los nodos de trabajo, tienes tus pods que se desplegarán en una máquina que pertenece a tu clúster pero no necesitas preocuparte por ello, ni gestionar nada relacionado con eso.

Así que, como hemos visto, el enfoque serverless está llegando a todas las áreas, pero este no es el alcance de este artículo. La idea aquí es tratar de centrarse en serverless como sinónimo de Función como Servicio (FaaS) y cómo podemos llevar la experiencia FaaS a nuestro ecosistema productivo de K8S. Pero comencemos con las preguntas iniciales:

¿Por qué querríamos hacer eso?

Esta es la cosa más emocionante de preguntar: ¿cuáles son los beneficios que proporciona este enfoque? Función como Servicio sigue el enfoque de escala cero. Eso significa que la función no se carga si no se está ejecutando, y esto es importante, especialmente cuando eres responsable de tu infraestructura o al menos estás pagando por ella.

Imagina un microservicio normal escrito en cualquier tecnología, la cantidad de recursos que puede usar depende de su carga, pero incluso sin ninguna carga, necesitas algunos recursos para mantenerlo en funcionamiento; principalmente, estamos hablando de memoria que necesitas mantener en uso. La cantidad real dependerá de la tecnología y del desarrollo en sí, pero puede moverse de algunos MB a algunos cientos. Si consideramos todos los microservicios que una empresa significativa puede tener, obtendrás una diferencia de varios GB que estás pagando y que no están proporcionando ningún valor.

Pero más allá de la gestión de infraestructura, este enfoque también juega muy bien con otro de los últimos enfoques arquitectónicos, la Aplicación Basada en Eventos (EDA), porque podemos tener servicios que están dormidos solo esperando el evento correcto para despertarlos y comenzar a procesar.

Entonces, en resumen, el enfoque serverless te ayuda a obtener tu sueño de infraestructura optimizada y habilitar diferentes patrones también de manera eficiente. Pero, ¿qué pasa si ya poseo la infraestructura? Será lo mismo porque ejecutarás más servicios en la misma infraestructura, por lo que aún obtendrás el uso optimizado de tu infraestructura actual.

¿Qué necesitamos para habilitar eso?

Lo primero que necesitamos saber es que no todas las tecnologías o marcos son adecuados para ejecutarse en este enfoque. Eso se debe a que necesitas cumplir con algunos requisitos para poder hacerlo como un enfoque exitoso, como se muestra a continuación:

  • Inicio Rápido: Si tu lógica no está cargada antes de que una solicitud llegue al servicio, necesitarás asegurarte de que la lógica pueda cargarse rápidamente para evitar impactar al consumidor del servicio. Eso significa que necesitarás una tecnología que pueda cargarse en una pequeña cantidad de tiempo, generalmente hablando en el rango de microsegundos.
  • Sin Estado: Como tu lógica no se va a cargar en un modo continuo, no es adecuada para servicios con estado.
  • Descarte: Similar al punto anterior, debe estar listo para un apagado elegante de manera robusta.

¿Cómo hacemos eso?

Varios marcos nos permiten obtener todos esos beneficios que podemos incorporar en nuestro ecosistema de Kubernetes, como los siguientes:

  • KNative: Este es el marco que la Fundación CNCF apoya y se está incluyendo por defecto en muchas distribuciones de Kubernetes como Red Hat Openshift Platform.
  • OpenFaaS: Este es un marco muy utilizado creado por Alex Ellis que apoya la misma idea.

Es cierto que hay otras alternativas como Apache OpenWhisk, Kubeless o Fission, pero son menos utilizadas en el mundo actual y principalmente la mayoría de las alternativas han sido elegidas entre OpenFaaS y KNative, pero si quieres leer más sobre otras alternativas te dejaré un artículo sobre la CNCF cubriéndolas para que puedas echar un vistazo por ti mismo:

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

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.