Prevención de Divulgación de Información con Istio Service Mesh

Prevención de Divulgación de Información con Istio Service Mesh

En el panorama digital actual, donde las violaciones de datos y las amenazas cibernéticas se están volviendo cada vez más sofisticadas, garantizar la seguridad de sus servidores es primordial. Una de las preocupaciones críticas de seguridad que las organizaciones deben abordar es la «Divulgación de Información del Servidor». La Divulgación de Información del Servidor ocurre cuando información sensible sobre la configuración de un servidor, su pila tecnológica o estructura interna se expone inadvertidamente a partes no autorizadas. Los hackers pueden explotar esta vulnerabilidad para obtener información sobre posibles puntos débiles y lanzar ataques dirigidos. Tales violaciones pueden llevar al robo de datos, interrupción del servicio y daño a la reputación.

Divulgación de Información y Malla de Servicios Istio

Un ejemplo es el Encabezado HTTP del Servidor, que generalmente se incluye en la mayoría de las respuestas HTTP donde se encuentra el servidor que está proporcionando esta respuesta. Los valores pueden variar dependiendo de la pila, pero asuntos como Jetty, Tomcat o similares suelen verse. Pero también, si está utilizando una Malla de Servicios como Istio, verá el encabezado con un valor de istio-envoy, como puede ver aquí:

Divulgación de Información de Implementación del Servidor usando Malla de Servicios Istio

Como se comentó, esto es de tal importancia para varios niveles de seguridad, tales como:

  • Privacidad de Datos: La fuga de información del servidor puede exponer datos confidenciales, socavando la confianza del usuario y violando regulaciones de privacidad de datos como GDPR y HIPAA.
  • Reducción de la Superficie de Ataque: Al ocultar los detalles del servidor, minimiza la superficie de ataque disponible para posibles atacantes.
  • Seguridad por Oscuridad: Aunque no es un enfoque infalible, limitar la divulgación agrega una capa extra de seguridad, dificultando que los hackers recopilen información.

¿Cómo mitigar eso con la Malla de Servicios Istio?

Al usar Istio, podemos definir diferentes reglas para agregar y eliminar encabezados HTTP según nuestras necesidades, como puede ver en la siguiente documentación aquí: https://discuss.istio.io/t/remove-header-operation/1692 usando cláusulas simples para la definición de su VirtualService como puede ver aquí:

apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
  name: k8snode-virtual-service
spec:
  hosts:
  - "example.com"
  gateways:
  - k8snode-gateway
  http:
    headers:
      response:
        remove:
          - "x-my-fault-source"
  - route:
    - destination:
        host: k8snode-service
        subset: version-1 

Desafortunadamente, esto no es útil para todos los encabezados HTTP, especialmente los «principales», por lo que los que no son personalizados agregados por sus cargas de trabajo, sino los que son principalmente utilizados y definidos en el estándar HTTP W3C https://www.w3.org/Protocols/

Entonces, en el caso del encabezado HTTP del Servidor es un poco más complejo de hacer, y necesita usar un EnvoyFilter, uno de los objetos más sofisticados que forma parte de la Malla de Servicios Istio. Basado en las palabras de la documentación oficial de Istio, un EnvoyFilter proporciona un mecanismo para personalizar la configuración de Envoy generada por Istio Pilot. Por lo tanto, puede usar EnvoyFilter para modificar valores para ciertos campos, agregar filtros específicos o incluso agregar nuevos oyentes, clústeres, etc.

Implementación de EnvoyFilter para Eliminar Encabezado

Así que ahora que sabemos que necesitamos crear un EnvoyFilter personalizado, veamos cuál necesitamos usar para eliminar el encabezado del Servidor y cómo se hace esto para obtener más conocimiento sobre este componente. Aquí puede ver el EnvoyFilter para ese trabajo:

---
apiVersion: networking.istio.io/v1alpha3
kind: EnvoyFilter
metadata:
  name: gateway-response-remove-headers
  namespace: istio-system
spec:
  workloadSelector:
    labels:
      istio: ingressgateway
  configPatches:
  - applyTo: NETWORK_FILTER
    match:
      context: GATEWAY
      listener:
        filterChain:
          filter:
            name: "envoy.filters.network.http_connection_manager"
    patch:
      operation: MERGE
      value:
        typed_config:
          "@type": "type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager"
          server_header_transformation: PASS_THROUGH
  - applyTo: ROUTE_CONFIGURATION
    match:
      context: GATEWAY
    patch:
      operation: MERGE
      value:
        response_headers_to_remove:
        - "server"

Así que centrémonos en las partes de la especificación del EnvoyFilter donde podemos obtener por un lado el usual workloadSelector, para saber dónde se aplicará este componente, que en este caso será el istio ingressgateway. Luego entramos en la sección configPatches, que son las secciones donde usamos la personalización que necesitamos hacer, y en nuestro caso, tenemos dos de ellas:

Ambas actúan en el contexto: GATEWAY y se aplican a dos objetos diferentes: NETWORK_FILTER Y ROUTE_CONFIGURATION. También puede usar filtros en sidecars para afectar su comportamiento. La primera parte lo que hace es incluir el filtro personalizado http_connection_manager que permite la manipulación del contexto HTTP, incluyendo para nuestro propósito principal también el encabezado HTTP, y luego tenemos la segunda parte que actúa en el ROUTE_CONFIGURATION eliminando el encabezado del servidor como podemos ver usando la opción response_header_to_remove

Conclusión

Como puede ver, esto no es fácil de implementar. Sin embargo, al mismo tiempo, es evidencia del poder y las capacidades de bajo nivel que tiene al usar una malla de servicios robusta como Istio para interactuar y modificar el comportamiento de cualquier pequeño detalle que desee para su beneficio y, en este caso, también para mejorar y aumentar la seguridad de sus cargas de trabajo desplegadas detrás del alcance de la Malla de Servicios.

En el panorama en constante evolución de las amenazas de ciberseguridad, proteger sus servidores contra la divulgación de información es crucial para proteger datos sensibles y mantener la integridad de su organización. Istio le permite fortalecer la seguridad de su servidor al proporcionar herramientas robustas para la gestión del tráfico, el cifrado y el control de acceso.

Recuerde, la clave para una seguridad adecuada del servidor es un enfoque proactivo que aborde las vulnerabilidades antes de que puedan ser explotadas. Tome la iniciativa de implementar Istio y eleve la protección de su servidor.

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

Mejorando la Resolución DNS del Service Mesh con la Capacidad de Proxy DNS de Istio: Beneficios y Casos de Uso

Mejorando la Resolución DNS del Service Mesh con la Capacidad de Proxy DNS de Istio: Beneficios y Casos de Uso

Istio es un popular service mesh de código abierto que proporciona una gama de potentes características para gestionar y asegurar arquitecturas basadas en microservicios. Hemos hablado mucho sobre sus capacidades y componentes, pero hoy hablaremos sobre cómo podemos usar Istio para ayudar con el mecanismo de resolución de DNS.

Como ya sabes, en una implementación típica de Istio, cada servicio está acompañado por un proxy sidecar, Envoy, que intercepta y gestiona el tráfico entre servicios. La capacidad de Proxy DNS de Istio aprovecha este proxy para manejar las solicitudes de resolución de DNS de manera más inteligente y eficiente.

Tradicionalmente, cuando un servicio dentro de una arquitectura de microservicios necesita comunicarse con otro servicio, depende de la resolución de DNS para descubrir la dirección IP del servicio objetivo. Sin embargo, la resolución de DNS tradicional puede ser difícil de gestionar en entornos complejos y dinámicos, como los que se encuentran en los clústeres de Kubernetes. Aquí es donde entra en juego la capacidad de Proxy DNS de Istio.

 Capacidades de Proxy DNS de Istio

Con Proxy DNS, Istio intercepta y controla las solicitudes de resolución de DNS de los servicios y realiza la resolución en su nombre. En lugar de depender de servidores DNS externos, los proxies sidecar manejan la resolución de DNS dentro del service mesh. Esto permite a Istio proporcionar varios beneficios valiosos:

  • Descubrimiento de servicios y balanceo de carga: El Proxy DNS de Istio permite mecanismos de descubrimiento de servicios más avanzados. Puede descubrir dinámicamente servicios y sus direcciones IP correspondientes dentro del mesh y realizar balanceo de carga entre instancias de un servicio en particular. Esto elimina la necesidad de que los servicios individuales gestionen la resolución de DNS y el balanceo de carga.
  • Seguridad y observabilidad: Istio obtiene visibilidad en el tráfico entre servicios al manejar la resolución de DNS dentro del mesh. Puede aplicar políticas de seguridad, como control de acceso y encriptación de tráfico, a nivel de DNS. Además, Istio puede recopilar datos de telemetría relacionados con DNS para monitoreo y observabilidad, proporcionando información sobre los patrones de comunicación entre servicios.
  • Gestión y control del tráfico: Proxy DNS permite a Istio implementar características avanzadas de gestión de tráfico, como reglas de enrutamiento e inyección de fallos, a nivel de resolución de DNS. Esto permite mecanismos sofisticados de control de tráfico dentro del service mesh, habilitando pruebas A/B, implementaciones canarias, ruptura de circuitos y otras estrategias de gestión de tráfico.

 Casos de Uso de Proxy DNS de Istio

Hay algunos momentos en los que no puedes o no quieres depender de la resolución normal de DNS. ¿Por qué es eso? Comenzando porque DNS es un gran protocolo pero carece de algunas capacidades, como el descubrimiento de ubicación. Si tienes el mismo DNS asignado a tres IPs, proporcionará cada una de ellas de manera circular y no puede depender de la ubicación.

O tienes varias IPs, y quieres bloquear algunas de ellas para algún servicio específico; estas son grandes cosas que puedes hacer con Istio Proxy DNS.

Habilitación de Proxy DNS de Istio

Debes saber que las capacidades de Proxy DNS de Istio no están habilitadas por defecto, por lo que debes ayudar si deseas usarlo. Lo bueno es que puedes permitirlo en diferentes niveles, desde el nivel completo del mesh hasta solo el nivel de un pod individual, por lo que puedes elegir lo que es mejor para ti en cada caso.

Por ejemplo, si queremos habilitarlo a nivel de pod, necesitamos inyectar la siguiente configuración en el proxy de Istio:

    proxy.istio.io/config: |
		proxyMetadata:   
         # Habilitar proxy DNS básico
         ISTIO_META_DNS_CAPTURE: "true" 
         # Habilitar asignación automática de direcciones, opcional
         ISTIO_META_DNS_AUTO_ALLOCATE: "true"

La misma configuración puede ser parte del nivel del Mesh como parte de la instalación del operador, como puedes encontrar la documentación aquí en la página oficial de Istio.

Conclusión

En resumen, la capacidad de Proxy DNS de Istio mejora el mecanismo de resolución de DNS dentro del entorno del service mesh, proporcionando descubrimiento de servicios avanzado, balanceo de carga, seguridad, observabilidad y características de gestión de tráfico. Istio centraliza y controla la resolución de DNS aprovechando los proxies sidecar, simplificando la gestión y optimización de la comunicación entre servicios en arquitecturas de microservicios complejas.

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

Explorando las Políticas de Seguridad de Istio para una Protección Mejorada de la Malla de Servicios con 3 Objetos

Explorando las Políticas de Seguridad de Istio para una Protección Mejorada de la Malla de Servicios con 3 Objetos

Las Políticas de Seguridad de Istio son cruciales para asegurar los microservicios dentro de un entorno de malla de servicios. Hemos discutido Istio y las capacidades que puede introducir a tus cargas de trabajo de Kubernetes. Sin embargo, hoy vamos a ser más detallados respecto a los diferentes objetos y recursos que nos ayudarían a hacer nuestras cargas de trabajo mucho más seguras y a reforzar la comunicación entre ellas. Estos objetos incluyen los objetos PeerAuthentication, RequestAuthentication y AuthorizationPolicy.

PeerAuthentication: Aplicando seguridad en la comunicación de pod a pod

PeerAuthentication se centra en asegurar la comunicación entre servicios aplicando autenticación y autorización mutua TLS (Transport Layer Security). Permite a los administradores definir políticas de autenticación para cargas de trabajo basadas en la fuente de las solicitudes, como namespaces específicos o cuentas de servicio. Configurar PeerAuthentication asegura que solo los servicios autenticados y autorizados puedan comunicarse, previniendo el acceso no autorizado y los ataques de intermediarios. Esto se puede lograr dependiendo del valor del modo donde se define este objeto siendo STRICT para solo permitir comunicación mTLS, PERMISSIVE para permitir ambos tipos de comunicación, DISABLE para prohibir la conexión mTLS y mantener el tráfico inseguro, y UNSET para usar la opción heredada. Este es un ejemplo de la definición del objeto:

apiVersion: security.istio.io/v1beta1
kind: PeerAuthentication
metadata:
  name: default
  namespace: foo
spec:
  mtls:
    mode: PERMISSIVE

RequestAuthentication: Definiendo métodos de autenticación para cargas de trabajo de Istio

RequestAuthentication, por otro lado, proporciona un control detallado sobre la autenticación de solicitudes entrantes. Permite a los administradores especificar reglas y requisitos para validar y autenticar solicitudes entrantes basadas en factores como la validación de JWT (JSON Web Tokens), claves API o métodos de autenticación personalizados. Con RequestAuthentication, los propietarios de servicios pueden aplicar mecanismos de autenticación específicos para diferentes puntos finales o rutas, asegurando que solo los clientes autenticados puedan acceder a recursos protegidos. Aquí puedes ver un ejemplo de un objeto RequestAuthentication:

apiVersion: security.istio.io/v1beta1
kind: RequestAuthentication
metadata:
  name: jwt-auth-policy
  namespace: my-namespace
spec:
  selector:
    matchLabels:
      app: my-app
  jwtRules:
    - issuer: "issuer.example.com"
      jwksUri: "https://example.com/.well-known/jwks.json"

Como se comentó, la validación de JWT es el enfoque más utilizado ya que los tokens JWT se están convirtiendo en el estándar de la industria para validaciones entrantes y el protocolo de autorización OAuth V2. Aquí puedes definir las reglas que el JWT necesita cumplir para ser considerado una solicitud válida. Pero el RequestAuthentication solo describe los “métodos de autenticación” soportados por las cargas de trabajo pero no lo aplica ni proporciona detalles sobre la Autorización.

Eso significa que si defines que una carga de trabajo necesita usar autenticación JWT, enviar la solicitud con el token validará ese token y asegurará que no esté expirado. Cumple con todas las reglas que has especificado en la definición del objeto, pero también permitirá pasar solicitudes sin token alguno, ya que solo estás definiendo lo que las cargas de trabajo soportan pero no lo aplicas. Para hacer eso, necesitamos introducir el último objeto de este conjunto, el objeto AuthorizationPolicy.

AuthorizationPolicy: Definición de Políticas de Autorización Detalladas para Políticas de Istio

AuthorizationPolicy ofrece potentes capacidades de control de acceso para regular el flujo de tráfico dentro de la malla de servicios. Permite a los administradores definir reglas y condiciones basadas en atributos como fuente, destino, encabezados e incluso carga útil de la solicitud para determinar si una solicitud debe ser permitida o denegada. AuthorizationPolicy ayuda a aplicar reglas de autorización detalladas, otorgando o denegando acceso a recursos o acciones específicas basadas en las políticas definidas. Solo los clientes autorizados con permisos apropiados pueden acceder a puntos finales específicos o realizar operaciones particulares dentro de la malla de servicios. Aquí puedes ver un ejemplo de un objeto Authorization Policy:

apiVersion: security.istio.io/v1beta1
kind: AuthorizationPolicy
metadata:
  name: rbac-policy
  namespace: my-namespace
spec:
  selector:
    matchLabels:
      app: my-app
  rules:
    - from:
        - source:
            principals: ["user:user@example.com"]
      to:
        - operation:
            methods: ["GET"]

Aquí puedes ser tan detallado como necesites; puedes aplicar reglas sobre la fuente de la solicitud para asegurar que solo algunas recomendaciones puedan pasar (por ejemplo, solicitudes que provienen de un token JWT para usar en combinación con el objeto RequestAuthentication), pero también reglas sobre el destino, si esto va a un host o ruta específica o método o una combinación de ambos. Además, puedes aplicar reglas de PERMITIR o DENEGAR (o incluso PERSONALIZADAS) y definir un conjunto de ellas, y todas se aplicarán en su conjunto. La evaluación se determina por las siguientes reglas como se indica en la Documentación Oficial de Istio:

  • Si hay políticas PERSONALIZADAS que coinciden con la solicitud, evalúa y niega la solicitud si el resultado de la evaluación es denegado.
  • Si hay políticas de DENEGAR que coinciden con la solicitud, niega la solicitud.
  • Si no hay políticas de PERMITIR para la carga de trabajo, permite la solicitud.
  • Si alguna de las políticas de PERMITIR coincide con la solicitud, permite la solicitud. Niega la solicitud.
Flujo de validación de la Política de Autorización de: https://istio.io/latest/docs/concepts/security/

Esto proporcionará todos los requisitos que podrías necesitar para poder hacer una definición completa de todas las políticas de seguridad necesarias.

 Conclusión

En conclusión, las Políticas de Seguridad de Istio proporcionan mecanismos robustos para mejorar la seguridad de los microservicios dentro de un entorno de malla de servicios. Los objetos PeerAuthentication, RequestAuthentication y AuthorizationPolicy ofrecen un conjunto de herramientas integral para aplicar controles de autenticación y autorización, asegurando la comunicación segura y el control de acceso dentro de la malla de servicios. Al aprovechar estas Políticas de Seguridad de Istio, las organizaciones pueden fortalecer la postura de seguridad de sus microservicios, protegiendo datos sensibles y previniendo el acceso no autorizado o actividades maliciosas dentro de su entorno de malla de servicios.

¿Cómo habilitar la sesión persistente en tus cargas de trabajo de Kubernetes usando Istio?

¿Cómo habilitar la sesión persistente en tus cargas de trabajo de Kubernetes usando Istio?

Istio te permite configurar Sticky Session, entre otras características de red, para tus cargas de trabajo de Kubernetes. Como hemos comentado en varios artículos sobre Istio, istio despliega una malla de servicios que proporciona un plano de control central para tener toda la configuración relacionada con los aspectos de red de tus cargas de trabajo de Kubernetes. Esto cubre muchos aspectos diferentes de la comunicación dentro de la plataforma de contenedores, como la seguridad que cubre el transporte seguro, la autenticación o la autorización, y, al mismo tiempo, características de red, como el enrutamiento y la distribución de tráfico, que es el tema principal del artículo de hoy.

Estas capacidades de enrutamiento son similares a lo que un Balanceador de Carga tradicional de Nivel 7 puede proporcionar. Cuando hablamos de Nivel 7, nos referimos a los niveles convencionales que componen la pila OSI, donde el nivel 7 está relacionado con el Nivel de Aplicación.

Una configuración de Sticky Session o Afinidad de Sesión es una de las características más comunes que puedes necesitar implementar en este escenario. El caso de uso es el siguiente:

¿Cómo habilitar Sticky Session en tus cargas de trabajo de Kubernetes usando Istio?

Tienes varias instancias de tus cargas de trabajo, por lo que diferentes réplicas de pods en una situación de Kubernetes. Todos estos pods detrás del mismo servicio. Por defecto, redirigirá las solicitudes de manera round-robin entre las réplicas de pods en un estado Ready, por lo que Kubernetes entiende que están listas para recibir la solicitud a menos que lo definas de manera diferente.

Pero en algunos casos, principalmente cuando estás tratando con una aplicación web o cualquier aplicación con estado que maneja el concepto de una sesión, podrías querer que la réplica que procesa la primera solicitud también maneje el resto de las solicitudes durante la vida útil de la sesión.

Por supuesto, podrías hacer eso fácilmente simplemente enrutando todo el tráfico a una solicitud, pero en ese caso, perderíamos otras características como el balanceo de carga de tráfico y HA. Entonces, esto generalmente se implementa usando políticas de Afinidad de Sesión o Sticky Session que proporcionan lo mejor de ambos mundos: la misma réplica manejando todas las solicitudes de un usuario, pero distribución de tráfico entre diferentes usuarios.

¿Cómo funciona Sticky Session?

El comportamiento detrás de esto es relativamente fácil. Veamos cómo funciona.

Primero, lo importante es que necesitas «algo» como parte de tus solicitudes de red que identifique todas las solicitudes que pertenecen a la misma sesión, para que el componente de enrutamiento (en este caso, este rol lo desempeña istio) pueda determinar qué parte necesita manejar estas solicitudes.

Este «algo» que usamos para hacer eso, puede ser diferente dependiendo de tu configuración, pero generalmente, esto es una Cookie o un Encabezado HTTP que enviamos en cada solicitud. Por lo tanto, sabemos que la réplica maneja todas las solicitudes de ese tipo específico.

¿Cómo implementa Istio el soporte para Sticky Session?

En el caso de usar Istio para desempeñar este rol, podemos implementar eso usando una Regla de Destino específica que nos permite, entre otras capacidades, definir la política de tráfico para definir cómo queremos que se divida el tráfico y para implementar el Sticky Session necesitamos usar la característica “consistentHash”, que permite que todas las solicitudes que se computan al mismo hash sean enviadas a la réplica.

Cuando definimos las características de consistentHash, podemos decir cómo se creará este hash y, en otras palabras, qué componentes se usarán para generar este hash, y esto puede ser una de las siguientes opciones:

  • httpHeaderName: Usa un Encabezado HTTP para hacer la distribución de tráfico
  • httpCookie: Usa una Cookie HTTP para hacer la distribución de tráfico
  • httpQueryParameterName: Usa una Cadena de Consulta para hacer la Distribución de Tráfico.
  • maglev: Usa el Balanceador de Carga Maglev de Google para hacer la determinación. Puedes leer más sobre Maglev en el artículo de Google.
  • ringHash: Usa un enfoque de hash basado en anillo para el balanceo de carga entre los pods disponibles.

Entonces, como puedes ver, tendrás muchas opciones diferentes. Aún así, solo las tres primeras serían las más utilizadas para implementar una sesión persistente, y generalmente, la opción de Cookie HTTP (httpCookie) será la preferida, ya que se basaría en el enfoque HTTP para gestionar la sesión entre clientes y servidores.

Ejemplo de Implementación de Sticky Session usando TIBCO BW

Definiremos una carga de trabajo TIBCO BW muy simple para implementar un servicio REST, sirviendo una respuesta GET con un valor codificado. Para simplificar el proceso de validación, la aplicación registrará el nombre de host del pod para que rápidamente podamos ver quién está manejando cada una de las solicitudes:

¿Cómo habilitar Sticky Session en tus cargas de trabajo de Kubernetes usando Istio?

Desplegamos esto en nuestro clúster de Kubernetes y lo exponemos usando un servicio de Kubernetes; en nuestro caso, el nombre de este servicio será test2-bwce-srv

Además de eso, aplicamos la configuración de istio, que requerirá tres (3) objetos de istio: gateway, servicio virtual y la regla de destino. Como nuestro enfoque está en la regla de destino, intentaremos mantenerlo lo más simple posible en los otros dos objetos:

 apiVersion: networking.istio.io/v1beta1
kind: Gateway
metadata:
  name: default-gw
spec:
  selector:
    istio: ingressgateway
  servers:
  - hosts:
    - '*'
    port:
      name: http
      number: 80
      protocol: HTTP

Servicio Virtual:

apiVersion: networking.istio.io/v1beta1
kind: VirtualService
metadata:
  name: test-vs
spec:
  gateways:
  - default-gw
  hosts:
  - test.com
  http:
  - match:
    - uri:
        prefix: /
    route:
    - destination:
        host: test2-bwce-srv
        port:
          number: 8080

Y finalmente, la DestinationRule usará una httpCookie que llamaremos ISTIOD, como puedes ver en el fragmento a continuación:

apiVersion: networking.istio.io/v1beta1
kind: DestinationRule
metadata:
    name: default-sticky-dr
    namespace: default
spec:
    host: test2-bwce-srv.default.svc.cluster.local
    trafficPolicy:
      loadBalancer:
        consistentHash:
          httpCookie: 
            name: ISTIOID
            ttl: 60s

Ahora, que ya hemos comenzado nuestra prueba, y después de lanzar la primera solicitud, obtenemos una nueva Cookie que es generada por istio mismo que se muestra en la ventana de respuesta de Postman:

¿Cómo habilitar la sesión persistente en tus cargas de trabajo de Kubernetes usando Istio?

Esta solicitud ha sido manejada por una de las réplicas disponibles del servicio, como puedes ver aquí:

¿Cómo habilitar la sesión persistente en tus cargas de trabajo de Kubernetes usando Istio?

Todas las solicitudes subsiguientes de Postman ya incluyen la cookie, y todas ellas son manejadas desde el mismo pod:

¿Cómo habilitar la sesión persistente en tus cargas de trabajo de Kubernetes usando Istio?

Mientras que el registro de la otra réplica está vacío, ya que todas las solicitudes han sido enrutadas a ese pod específico.

¿Cómo habilitar la sesión persistente en tus cargas de trabajo de Kubernetes usando Istio?

Resumen

Cubrimos en este artículo la razón detrás de la necesidad de una sesión persistente en la carga de trabajo de Kubernetes y cómo podemos lograr eso usando las capacidades de la Malla de Servicios de Istio. Así que, espero que esto pueda ayudar a implementar esta configuración en tus cargas de trabajo que puedas necesitar hoy o en el futuro.

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

Optimiza Tu Service Mesh con Istio y Extremos Externos

Optimiza Tu Service Mesh con Istio y Extremos Externos

¿Qué es un Istio ServiceEntry?

Istio ServiceEntry es la forma de definir un punto final que no pertenece al Registro de Servicios de Istio. Una vez que el ServiceEntry es parte del registro, puede definir reglas e imponer políticas como si pertenecieran al mesh.

Istio Service Entry responde a la pregunta que probablemente te has hecho varias veces al usar una Service Mesh. ¿Cómo puedo hacer la misma magia con puntos finales externos que puedo hacer cuando todo está bajo el alcance de mi malla de servicios? Y los objetos Istio Service Entry proporcionan precisamente eso:

Una forma de tener una malla extendida gestionando otro tipo de carga de trabajo o, aún mejor, en palabras del propio Istio:

ServiceEntry permite agregar entradas adicionales en el registro de servicios interno de Istio para que los servicios auto-descubiertos en la malla puedan acceder/rutear a estos servicios especificados manualmente.

Estos servicios podrían ser externos a la malla (por ejemplo, APIs web) o servicios internos de la malla que no son parte del registro de servicios de la plataforma (por ejemplo, un conjunto de VMs comunicándose con servicios en Kubernetes).

¿Cuáles son las principales capacidades de Istio ServiceEntry?

Aquí puedes ver un ejemplo de la definición YAML de un Service Entry:

apiVersion: networking.istio.io/v1beta1
kind: ServiceEntry
metadata:
  name: external-svc-redirect
spec:
  hosts:
  - wikipedia.org
  - "*.wikipedia.org"
  location: MESH_EXTERNAL
  ports:
  - number: 443
    name: https
    protocol: TLS
  resolution: NONE

En este caso, tenemos un objeto external-svc-redirectServiceEntry que está manejando todas las llamadas que van a wikipedia.org, y definimos el puerto y el protocolo a utilizar (TLS – 443) y clasificamos este servicio como externo a la malla (MESH_EXTERNAL) ya que es una página web externa.

También puedes especificar más detalles dentro de la configuración de ServiceEntry, para que puedas, por ejemplo, definir un nombre de host o IP y traducirlo a un nombre de host y puerto diferentes porque también puedes especificar el modo de resolución que deseas usar para este Service Entry específico. Si ves el fragmento anterior, encontrarás un campo resolution con el valor NONE que indica que no hará ninguna resolución particular. Pero otros valores válidos son los siguientes:

  • NONE: Asume que las conexiones entrantes ya han sido resueltas (a una dirección IP de destino específica).
  • STATIC: Usa las direcciones IP estáticas especificadas en los puntos finales como las instancias de respaldo asociadas con el servicio.
  • DNS: Intenta resolver la dirección IP consultando el DNS ambiental de manera asincrónica.
  • DNSROUNDROBIN: Intenta resolver la dirección IP consultando el DNS ambiental de manera asincrónica. A diferencia de DNS, DNSROUNDROBIN solo usa la primera dirección IP devuelta cuando se necesita iniciar una nueva conexión sin depender de los resultados completos de la resolución DNS, y las referencias hechas a los hosts se mantendrán incluso si los registros DNS cambian con frecuencia, eliminando el drenaje de grupos de conexiones y el ciclo de conexiones.

Para definir el objetivo del ServiceEntry, necesitas especificar sus puntos finales utilizando un objeto WorkloadEntry. Para hacerlo, necesitas proporcionar los siguientes datos:

  • address: Dirección asociada con el punto final de la red sin el puerto.
  • ports: Conjunto de puertos asociados con el punto final
  • weight: El peso de balanceo de carga asociado con el punto final.
  • locality: La localidad asociada con el punto final. Una localidad corresponde a un dominio de falla (por ejemplo, país/región/zona).
  • network: La red permite a Istio agrupar puntos finales residentes en el mismo dominio/red L3.

¿Qué puedes hacer con Istio ServiceEntry?

El número de casos de uso es enorme. Una vez que un ServiceEntry es similar a lo que tienes definido un Servicio Virtual, puedes aplicar cualquier regla de destino a ellos para hacer un balanceador de carga, un cambio de protocolo, o cualquier lógica que se pueda hacer con el objeto DestinationRule. Lo mismo se aplica al resto de los CRD de Istio, como RequestAuthentication y PeerAuthorization, entre otros.

También puedes tener una representación gráfica del ServiceEntry dentro de Kiali, una representación visual para la Malla de Servicios de Istio, como puedes ver en la imagen a continuación:

Entendiendo Istio ServiceEntry: Cómo Extender Tu Malla de Servicios a Puntos Finales Externos

Como puedes definir, una malla extendida con puntos finales fuera del clúster de Kubernetes es algo que se está volviendo más común con la explosión de clústeres disponibles y los entornos híbridos cuando necesitas gestionar clústeres de diferentes topologías y no perder la gestión centralizada basada en políticas de red que la Malla de Servicios de Istio proporciona a tu plataforma.

Asegure sus servicios con Istio: Guía paso a paso para configurar conexiones TLS de Istio

Asegure sus servicios con Istio: Guía paso a paso para configurar conexiones TLS de Istio

Introducción

La configuración de TLS en Istio es una de las características esenciales cuando habilitamos un Service Mesh. Istio Service Mesh proporciona muchas características para definir de manera centralizada y con políticas cómo se maneja la seguridad de transporte, entre otras características, en las diferentes cargas de trabajo que has desplegado en tu clúster de Kubernetes.

Una de las principales ventajas de este enfoque es que puedes hacer que tu aplicación se concentre en la lógica de negocio que necesita implementar. Estos aspectos de seguridad pueden externalizarse y centralizarse sin necesariamente incluir un esfuerzo adicional en cada aplicación que hayas desplegado. Esto es especialmente relevante si estás siguiendo un enfoque poliglota (como deberías) en las cargas de trabajo de tu clúster de Kubernetes.

Así que, esta vez vamos a hacer que nuestras aplicaciones manejen solo tráfico HTTP tanto interno como externo, y dependiendo de a dónde estemos llegando, forzaremos que esa conexión sea TLS sin que la carga de trabajo necesite ser consciente de ello. Así que, veamos cómo podemos habilitar esta configuración de TLS en Istio.

Vista del Escenario

Usaremos esta imagen que puedes ver a continuación para tener en mente los conceptos y componentes que interactuarán como parte de las diferentes configuraciones que aplicaremos a esto.

  • Usaremos la puerta de enlace de entrada para manejar todo el tráfico entrante al clúster de Kubernetes y la puerta de enlace de salida para manejar todo el tráfico saliente del clúster.
  • Tendremos un contenedor sidecar desplegado en cada aplicación para manejar la comunicación desde las puertas de enlace o la comunicación de pod a pod.

Para simplificar las aplicaciones de prueba, usaremos las aplicaciones de muestra predeterminadas que Istio proporciona, las cuales puedes encontrar aquí.

¿Cómo Exponer TLS en Istio?

Esta es la parte más fácil, ya que toda la comunicación entrante que recibirás desde el exterior entrará al clúster a través de la Puerta de Enlace de Ingreso de Istio, por lo que es este componente el que necesita manejar la conexión TLS y luego usar el enfoque de seguridad habitual para hablar con el pod que expone la lógica.

Por defecto, la Puerta de Enlace de Ingreso de Istio ya expone un puerto TLS, como puedes ver en la imagen a continuación:

Asegura tus servicios con Istio: Una guía paso a paso para configurar conexiones TLS en Istio

Así que necesitaremos definir una Puerta de Enlace que reciba todo este tráfico a través de HTTPS y lo redirija a los pods, y lo haremos como puedes ver aquí:

apiVersion: networking.istio.io/v1alpha3
kind: Gateway
metadata:
  name: bookinfo-gateway-https
  namespace: default
spec:
  selector:
    istio: ingressgateway
  servers:
    - hosts:
        - '*'
      port:
        name: https
        number: 443
        protocol: HTTPS
      tls:
        mode: SIMPLE # habilita HTTPS en este puerto
        credentialName: httpbin-credential 

Como podemos ver, es una configuración sencilla, solo agregando el puerto HTTPS en el 443 y proporcionando la configuración TLS:

Y con eso, ya podemos acceder usando SSL a las mismas páginas:

Asegura tus servicios con Istio: Una guía paso a paso para configurar conexiones TLS en Istio

¿Cómo Consumir SSL desde Istio?

Ahora que hemos generado una solicitud TLS entrante sin que la aplicación sepa nada, vamos un paso más allá y hacemos la configuración más desafiante. Configuraremos la conexión TLS/SSL para cualquier comunicación saliente fuera del clúster de Kubernetes sin que la aplicación sepa nada al respecto.

Para hacerlo, usaremos uno de los conceptos de Istio que ya hemos cubierto en un artículo específico. Ese concepto es la Entrada de Servicio de Istio que nos permite definir un punto final para gestionarlo dentro del MESH.

Aquí podemos ver el punto final de Wikipedia agregado al registro de Service Mesh:

 apiVersion: networking.istio.io/v1beta1
kind: ServiceEntry
metadata:
  name: se-app
  namespace: default
spec:
  hosts:
  - wikipedia.org
  ports:
  - name: https
    number: 443
    protocol: HTTPS
  resolution: DNS

Una vez que hemos configurado la Entrada de Servicio, podemos definir una Regla de Destino para forzar que todas las conexiones a wikipedia.org usen la configuración TLS:

apiVersion: networking.istio.io/v1beta1
kind: DestinationRule
metadata:
  name: tls-app
  namespace: default
spec:
  host: wikipedia.org
  trafficPolicy:
    tls:
      mode: SIMPLE

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

Kiali: Guía Esencial para Gestionar Istio Service Mesh

Kiali: Guía Esencial para Gestionar Istio Service Mesh

¿Qué es Kiali?

Kiali es un proyecto de código abierto que proporciona observabilidad para tu malla de servicios Istio. Desarrollado por Red Hat, Kiali ayuda a los usuarios a entender la estructura y el comportamiento de su malla y cualquier problema que pueda surgir.

Kiali proporciona una representación gráfica de tu malla, mostrando las relaciones entre los diversos componentes de la malla de servicios, como servicios, servicios virtuales, reglas de destino y más. También muestra métricas vitales, como tasas de solicitudes y errores, para ayudarte a monitorear la salud de tu malla e identificar posibles problemas.

 ¿Cuáles son las principales capacidades de Kiali?

Una de las características clave de Kiali es su capacidad para visualizar la comunicación de servicio a servicio dentro de una malla. Esto permite a los usuarios ver rápidamente cómo están conectados los servicios y cómo se enrutan las solicitudes a través de la malla. Esto es particularmente útil para la resolución de problemas, ya que puede ayudarte a identificar rápidamente problemas con la comunicación de servicios, como reglas de enrutamiento mal configuradas o tiempos de respuesta lentos.

Kiali 101: Comprendiendo y Utilizando esta Herramienta Esencial de Gestión de Malla de Servicios

Kiali también proporciona varias herramientas para monitorear la salud de tu malla. Por ejemplo, puede alertarte sobre problemas potenciales, como una alta tasa de errores o un servicio que no responde a las solicitudes. También proporciona información de seguimiento detallada, permitiéndote ver el camino exacto que tomó una solicitud a través de la malla y dónde pudieron haber ocurrido problemas.

Además de sus características de observabilidad, Kiali proporciona varias otras herramientas para gestionar tu malla de servicios. Por ejemplo, incluye un módulo de gestión de tráfico, que te permite controlar fácilmente el flujo de tráfico a través de tu malla, y un módulo de gestión de configuración, que te ayuda a gestionar y mantener los diversos componentes de tu malla.

En general, Kiali es una herramienta esencial para cualquiera que use una malla de servicios Istio. Proporciona valiosos conocimientos sobre la estructura y el comportamiento de tu malla, así como potentes herramientas de monitoreo y gestión. Ya sea que estés comenzando con Istio o seas un usuario experimentado, Kiali puede ayudar a garantizar que tu malla de servicios funcione de manera fluida y eficiente.

¿Cuáles son los principales beneficios de usar Kiali?

Los principales beneficios de usar Kiali son:

  • Mejorada observabilidad de tu malla de servicios Istio. Kiali proporciona una representación gráfica de tu malla, mostrando las relaciones entre diferentes componentes de la malla de servicios y mostrando métricas clave. Esto te permite entender rápidamente la estructura y el comportamiento de tu malla e identificar posibles problemas.
  • Facilita la resolución de problemas. La visualización de Kiali de la comunicación de servicio a servicio y la información de seguimiento detallada facilitan la identificación de problemas con la comunicación de servicios y localizar la fuente de cualquier problema.
  • Mejorada gestión del tráfico. Kiali incluye un módulo de gestión de tráfico que te permite controlar fácilmente el flujo de tráfico a través de tu malla.
  • Mejorada gestión de configuración. El módulo de gestión de configuración de Kiali te ayuda a gestionar y mantener los diversos componentes de tu malla.

¿Cómo instalar Kiali?

Hay varias formas de instalar Kiali como parte de tu implementación de Malla de Servicios, siendo la opción preferida usar el modelo de Operador disponible aquí.

Puedes instalar este operador usando Helm o OperatorHub. Para instalarlo usando Helm Charts, necesitas agregar el siguiente repositorio usando este comando:

 helm repo add kiali https://kiali.org/helm-charts

** Recuerda que una vez que agregues un nuevo repositorio, necesitas ejecutar el siguiente comando para actualizar los charts disponibles

helm repo update

Ahora, puedes instalarlo usando el comando helm install tal como en el siguiente ejemplo:

helm install 
    --set cr.create=true 
    --set cr.namespace=istio-system 
    --namespace kiali-operator 
    --create-namespace 
    kiali-operator 
    kiali/kiali-operator

Si prefieres seguir la ruta de OperatorHub, puedes usar la siguiente URL . Ahora, al hacer clic en el botón de Instalar, verás los pasos para tener el componente instalado en tu entorno de Kubernetes.

Kiali 101: Comprendiendo y Utilizando esta Herramienta Esencial de Gestión de Malla de Servicios

En caso de que desees una instalación simple de Kiali, también puedes usar el YAML de muestra disponible dentro de la carpeta de instalación de Istio usando el siguiente comando:

kubectl apply -f $ISTIO_HOME/samples/addons/kiali.yaml

¿Cómo funciona Kiali?

Kiali es solo la representación gráfica de la información disponible sobre cómo funciona la malla de servicios. Por lo tanto, no es responsabilidad de Kiali almacenar esas métricas, sino recuperarlas y dibujarlas de manera relevante para el usuario de la herramienta.

Prometheus realiza el almacenamiento de estos datos, por lo que Kiali utiliza la API REST de Prometheus para recuperar la información y dibujarla gráficamente, como puedes ver aquí:

  • Va a mostrar varias partes relevantes del gráfico. Mostrará el espacio de nombres seleccionado y dentro de ellos las diferentes aplicaciones (detectará una aplicación en caso de que tengas una etiqueta agregada a la carga de trabajo con el nombre app ). Dentro de cada aplicación se agregarán diferentes servicios y pods con otros íconos (triángulos para los servicios y cuadrados para los pods).
  • También mostrará cómo el tráfico llega al clúster a través de las diferentes puertas de enlace de entrada y cómo sale en caso de que tengamos alguna puerta de enlace de salida configurada.
  • Mostrará el tipo de tráfico que estamos manejando y las diferentes tasas de error basadas en el tipo de protocolo, como TCP, HTTP, y así sucesivamente, como puedes ver en la imagen a continuación. El protocolo se decide en base a una convención de nombres en el nombre del puerto del servicio con el formato esperado: nombre-del-protocolo
Kiali 101: Comprendiendo y Utilizando esta Herramienta Esencial de Gestión de Malla de Servicios

¿Puede Kiali usarse con cualquier malla de servicios?

No, Kiali está diseñado específicamente para su uso con mallas de servicios Istio.

Proporciona herramientas de observabilidad, monitoreo y gestión para mallas de servicios Istio, pero no es compatible con otras tecnologías de malla de servicios.

Si usas una malla de servicios diferente, necesitarás encontrar una herramienta adicional para gestionarla y monitorearla.

¿Existen otras alternativas a Kiali?

Aunque no puedas ver alternativas naturales a Kiali para visualizar tus cargas de trabajo y tráfico a través de la Malla de Servicios Istio, puedes usar otras herramientas para obtener las métricas que alimentan a Kiali y tener una visualización personalizada usando herramientas más genéricas como Grafana, entre otras.

Hablemos de herramientas similares a Kiali para otras Mallas de Servicios, como Linkerd, Consul Connect, o incluso Kuma. La mayoría sigue un enfoque diferente donde la parte de visualización no es un «proyecto» separado, sino que se basa en una herramienta de visualización estándar. Eso te da mucha más flexibilidad, pero al mismo tiempo, carece de la excelente visualización del tráfico que proporciona Kiali, como vistas de gráficos o la capacidad de modificar el tráfico directamente desde la vista de gráficos.

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

Linkerd como la solución para resolver tus desafíos de comunicación en la arquitectura de microservicios

Linkerd como la solución para resolver tus desafíos de comunicación en la arquitectura de microservicios

El servicio Mesh Linkerd patrocinado por CNCF proporciona muchas características necesarias en las arquitecturas de microservicios actuales.

Si estás leyendo esto, probablemente ya estés al tanto de los desafíos que vienen con una arquitectura de microservicios. Podría ser porque estás leyendo sobre ellos o incluso porque los estás enfrentando ahora mismo en tu propia piel.

Uno de los desafíos más comunes es la red y la comunicación. Con la eclosión de muchos componentes que necesitan comunicación y el enfoque efímero de los desarrollos nativos de la nube, muchas características nuevas son una necesidad cuando en el pasado eran solo un «agradable de tener».

Conceptos como el registro de servicios y el descubrimiento de servicios, la autenticación de servicios, las políticas de enrutamiento dinámico y los patrones de disyuntor ya no son cosas que todas las empresas geniales están haciendo, sino algo básico para dominar la nueva arquitectura de microservicios como parte de una plataforma de arquitectura nativa de la nube, y aquí es donde el proyecto Service Mesh está aumentando su popularidad como una solución para la mayoría de estos desafíos y proporcionando estas características que se necesitan.

Si recuerdas, hace mucho tiempo, ya cubrí ese tema para presentar Istio como una de las opciones que tenemos:

Pero este proyecto creado por Google e IBM no es la única opción que tienes para proporcionar esas capacidades. Como parte de la Cloud Native Computing Foundation (CNCF), el proyecto Linkerd proporciona características similares.

Cómo instalar Linkerd

Para comenzar a usar Linkerd, lo primero que necesitamos hacer es instalar el software y para hacerlo. Necesitamos hacer dos instalaciones, una en el servidor de Kubernetes y otra en el host.

Para instalar en el host, necesitas ir a la página de lanzamientos y descargar la edición para tu sistema operativo e instalarla.

Estoy usando un sistema basado en Windows en mi ejemplo, así que uso chocolatey para instalar el cliente. Después de hacerlo, puedo ver la versión del CLI escribiendo el siguiente comando:

linkerd version

Y obtendrás una salida que dirá algo similar a esto:

PS C:WINDOWSsystem32> linkerd.exe version
Client version: stable-2.8.1
Server version: unavailable

Ahora necesitamos hacer la instalación en el servidor de Kubernetes, y para hacerlo, usamos el siguiente comando:

linkerd install | kubectl apply -f -

Y obtendrás una salida similar a esta:

PS C:WINDOWSsystem32> linkerd install | kubectl apply -f -
namespace/linkerd created
clusterrole.rbac.authorization.k8s.io/linkerd-linkerd-identity created
clusterrolebinding.rbac.authorization.k8s.io/linkerd-linkerd-identity created
serviceaccount/linkerd-identity created
clusterrole.rbac.authorization.k8s.io/linkerd-linkerd-controller created
clusterrolebinding.rbac.authorization.k8s.io/linkerd-linkerd-controller created
serviceaccount/linkerd-controller created
clusterrole.rbac.authorization.k8s.io/linkerd-linkerd-destination created
clusterrolebinding.rbac.authorization.k8s.io/linkerd-linkerd-destination created
serviceaccount/linkerd-destination created
role.rbac.authorization.k8s.io/linkerd-heartbeat created
rolebinding.rbac.authorization.k8s.io/linkerd-heartbeat created
serviceaccount/linkerd-heartbeat created
role.rbac.authorization.k8s.io/linkerd-web created
rolebinding.rbac.authorization.k8s.io/linkerd-web created
clusterrole.rbac.authorization.k8s.io/linkerd-linkerd-web-check created
clusterrolebinding.rbac.authorization.k8s.io/linkerd-linkerd-web-check created
clusterrolebinding.rbac.authorization.k8s.io/linkerd-linkerd-web-admin created
serviceaccount/linkerd-web created
customresourcedefinition.apiextensions.k8s.io/serviceprofiles.linkerd.io created
customresourcedefinition.apiextensions.k8s.io/trafficsplits.split.smi-spec.io created
clusterrole.rbac.authorization.k8s.io/linkerd-linkerd-prometheus created
clusterrolebinding.rbac.authorization.k8s.io/linkerd-linkerd-prometheus created
serviceaccount/linkerd-prometheus created
clusterrole.rbac.authorization.k8s.io/linkerd-linkerd-proxy-injector created
clusterrolebinding.rbac.authorization.k8s.io/linkerd-linkerd-proxy-injector created
serviceaccount/linkerd-proxy-injector created
secret/linkerd-proxy-injector-tls created
mutatingwebhookconfiguration.admissionregistration.k8s.io/linkerd-proxy-injector-webhook-config created
clusterrole.rbac.authorization.k8s.io/linkerd-linkerd-sp-validator created
clusterrolebinding.rbac.authorization.k8s.io/linkerd-linkerd-sp-validator created
serviceaccount/linkerd-sp-validator created
secret/linkerd-sp-validator-tls created
validatingwebhookconfiguration.admissionregistration.k8s.io/linkerd-sp-validator-webhook-config created
clusterrole.rbac.authorization.k8s.io/linkerd-linkerd-tap created
clusterrole.rbac.authorization.k8s.io/linkerd-linkerd-tap-admin created
clusterrolebinding.rbac.authorization.k8s.io/linkerd-linkerd-tap created
clusterrolebinding.rbac.authorization.k8s.io/linkerd-linkerd-tap-auth-delegator created
serviceaccount/linkerd-tap created
rolebinding.rbac.authorization.k8s.io/linkerd-linkerd-tap-auth-reader created
secret/linkerd-tap-tls created
apiservice.apiregistration.k8s.io/v1alpha1.tap.linkerd.io created
podsecuritypolicy.policy/linkerd-linkerd-control-plane created
role.rbac.authorization.k8s.io/linkerd-psp created
rolebinding.rbac.authorization.k8s.io/linkerd-psp created
configmap/linkerd-config created
secret/linkerd-identity-issuer created
service/linkerd-identity created
deployment.apps/linkerd-identity created
service/linkerd-controller-api created
deployment.apps/linkerd-controller created
service/linkerd-dst created
deployment.apps/linkerd-destination created
cronjob.batch/linkerd-heartbeat created
service/linkerd-web created
deployment.apps/linkerd-web created
configmap/linkerd-prometheus-config created
service/linkerd-prometheus created
deployment.apps/linkerd-prometheus created
deployment.apps/linkerd-proxy-injector created
service/linkerd-proxy-injector created
service/linkerd-sp-validator created
deployment.apps/linkerd-sp-validator created
service/linkerd-tap created
deployment.apps/linkerd-tap created
configmap/linkerd-config-addons created
serviceaccount/linkerd-grafana created
configmap/linkerd-grafana-config created
service/linkerd-grafana created
deployment.apps/linkerd-grafana created

Ahora podemos verificar que la instalación se ha realizado correctamente usando el comando:

linkerd check

Y si todo se ha hecho correctamente, obtendrás una salida como esta:

PS C:WINDOWSsystem32> linkerd check
kubernetes-api
--------------
√ can initialize the client
√ can query the Kubernetes API
kubernetes-version
------------------
√ is running the minimum Kubernetes API version
√ is running the minimum kubectl version
linkerd-existence
-----------------
√ 'linkerd-config' config map exists
√ heartbeat ServiceAccount exist
√ control plane replica sets are ready
√ no unschedulable pods
√ controller pod is running
√ can initialize the client
√ can query the control plane API
linkerd-config
--------------
√ control plane Namespace exists
√ control plane ClusterRoles exist
√ control plane ClusterRoleBindings exist
√ control plane ServiceAccounts exist
√ control plane CustomResourceDefinitions exist
√ control plane MutatingWebhookConfigurations exist
√ control plane ValidatingWebhookConfigurations exist
√ control plane PodSecurityPolicies exist
linkerd-identity
----------------
√ certificate config is valid
√ trust anchors are using supported crypto algorithm
√ trust anchors are within their validity period
√ trust anchors are valid for at least 60 days
√ issuer cert is using supported crypto algorithm
√ issuer cert is within its validity period
√ issuer cert is valid for at least 60 days
√ issuer cert is issued by the trust anchor

Luego podemos ver el panel de Linkerd usando el siguiente comando:

linkerd dashboard
Linkerd como la solución para resolver tus desafíos de comunicación en la arquitectura de microservicios
Página web inicial del panel después de una instalación limpia de Linkerd

Despliegue de las aplicaciones

Usaremos las mismas aplicaciones que usamos hace algún tiempo para desplegar istio, así que si quieres recordar lo que están haciendo, necesitas mirar de nuevo ese artículo.

He subido el código a mi repositorio de GitHub, y puedes encontrarlo aquí: https://github.com/alexandrev/bwce-linkerd-scenario

Para desplegar, necesitas tener tus imágenes de docker subidas a un registro de docker, y usaré Amazon ECR como el repositorio de docker que voy a usar.

Así que necesito construir y subir esas imágenes con los siguientes comandos:

docker build -t provider:1.0 .
docker tag provider:1.0 938784100097.dkr.ecr.eu-west-2.amazonaws.com/provider-linkerd:1.0
docker push 938784100097.dkr.ecr.eu-west-2.amazonaws.com/provider-linkerd:1.0
docker build -t consumer:1.0 .
docker tag consumer:1.0 938784100097.dkr.ecr.eu-west-2.amazonaws.com/consumer-linkerd:1.0
docker push 938784100097.dkr.ecr.eu-west-2.amazonaws.com/consumer-linkerd:1.0

Y después de eso, vamos a desplegar las imágenes en el clúster de Kubernetes:

kubectl apply -f .provider.yaml
kubectl apply -f .consumer.yaml

Y ahora podemos ver esas aplicaciones en el Panel de Linkerd en el espacio de nombres predeterminado:

Linkerd como la solución para resolver tus desafíos de comunicación en la arquitectura de microservicios
Imagen que muestra la aplicación proveedor y consumidor como aplicaciones vinculadas

Y ahora, podemos alcanzar el endpoint del consumidor usando el siguiente comando:

kubectl port-forward pod/consumer-v1-6cd49d6487-jjm4q 6000:6000

Y si alcanzamos el endpoint, obtuvimos la respuesta esperada del proveedor.

Linkerd como la solución para resolver tus desafíos de comunicación en la arquitectura de microservicios
Respuesta de muestra proporcionada por el proveedor

Y en el panel, podemos ver las estadísticas del proveedor:

Linkerd como la solución para resolver tus desafíos de comunicación en la arquitectura de microservicios
Panel de Linkerd mostrando las estadísticas del flujo

Además, Linkerd por defecto proporciona un panel de Grafana donde puedes ver más métricas, puedes llegar allí usando el enlace de grafana que tiene el panel.

Linkerd como la solución para resolver tus desafíos de comunicación en la arquitectura de microservicios
Enlace de Grafana en el Panel de Linkerd

Cuando entras, podrías ver algo como el panel que se muestra a continuación:

Linkerd como la solución para resolver tus desafíos de comunicación en la arquitectura de microservicios
Panel de Grafana mostrando las estadísticas de linkerd

Resumen

Con todo este proceso, hemos visto lo fácil que podemos desplegar un servicio mesh de linkerd en nuestro clúster de Kubernetes y cómo las aplicaciones pueden integrarse e interactuar con ellos. En los próximos posts, profundizaremos en las características más avanzadas que nos ayudarán en los nuevos desafíos que vienen con la arquitectura de Microservicios.

Guerras tecnológicas: Solución de Gestión de API vs Malla de Servicios

Guerras tecnológicas: Solución de Gestión de API vs Malla de Servicios

Service Mesh vs. Solución de Gestión de API: ¿es lo mismo? ¿Son compatibles? ¿Son rivales?

Cuando hablamos de comunicación en un mundo distribuido nativo de la nube y especialmente cuando hablamos de arquitecturas basadas en contenedores basadas en la plataforma Kubernetes como AKS, EKS, Openshift, etc., dos tecnologías generan mucha confusión porque parecen estar cubriendo las mismas capacidades: Esas son Service Mesh y Soluciones de Gestión de API.

Ha sido un tema controvertido donde se han hecho diferentes declaraciones audaces: Personas que piensan que esas tecnologías trabajan juntas de manera complementaria, otras que creen que están tratando de resolver los mismos problemas de diferentes maneras e incluso personas que piensan que una es solo la evolución de la otra hacia la nueva arquitectura nativa de la nube.

Soluciones de Gestión de API

Las Soluciones de Gestión de API han sido parte de nuestras arquitecturas durante mucho tiempo. Es un componente crucial de cualquier arquitectura hoy en día que se crea siguiendo los principios de la Arquitectura Guiada por API, y son una evolución del Gateway de API preexistente que hemos incluido como una evolución de los proxies puros a finales de los 90 y principios de los 2000.

La Solución de Gestión de API es un componente crítico de su Estrategia de API porque permite a su empresa trabajar en un Enfoque Guiado por API. Y eso es mucho más que el aspecto técnico de ello. Usualmente tratamos de simplificar el Enfoque Guiado por API al lado técnico con el desarrollo basado en API y los microservicios que estamos creando y el espíritu colaborativo en mente que usamos hoy para hacer cualquier pieza de software que se despliega en el entorno de producción.

Pero es mucho más que eso. Las Arquitecturas Guiadas por API se tratan de crear productos a partir de nuestra API, proporcionando todos los artefactos (técnicos y no técnicos) que necesitamos para hacer esa conversión. Una lista rápida de esos artefactos (pero no es una lista exhaustiva) son los siguientes:

  • Soporte de Documentación de API
  • Definición de Planes de Paquetes
  • Capacidades de Suscripción
  • Capacidades de Monetización
  • Descubrimiento de API de Autoservicio
  • Capacidades de Versionado

Tradicionalmente, la solución de Gestión de API también viene con capacidades de Gateway de API integradas para cubrir incluso el aspecto técnico de ello, y que también proporcionan algunas otras capacidades más a nivel técnico:

  • Exposición
  • Enrutamiento
  • Seguridad
  • Limitación

Service Mesh

Service Mesh es más una palabra de moda en estos días y una tecnología que ahora está en tendencia porque ha sido creada para resolver algunos de los desafíos que son inherentes al enfoque de microservicios y contenedores y todo bajo la etiqueta de nativo de la nube.

En este caso, proviene del lado técnico, por lo que es mucho más un enfoque de abajo hacia arriba porque su existencia es para poder resolver un problema técnico e intentar proporcionar una mejor experiencia de usuario a los nuevos desarrolladores y administradores de sistemas en este nuevo mundo mucho más complicado. ¿Y cuáles son los desafíos que se han creado en esta transición? Echemos un vistazo a ellos:

El Registro y Descubrimiento de Servicios es una de las cosas críticas que necesitamos cubrir porque con el paradigma elástico del mundo nativo de la nube hace que los servicios cambien su ubicación de vez en cuando comenzando en nuevas máquinas cuando sea necesario, eliminándolos cuando no hay suficiente carga para requerir su presencia, por lo que es esencial proporcionar una manera de gestionar fácilmente esa nueva realidad que no necesitábamos en el pasado cuando nuestros servicios estaban vinculados a una máquina específica o conjunto de dispositivos.

La seguridad es otro tema importante en cualquier arquitectura que podamos crear hoy, y con el enfoque poliglota que hemos incorporado en nuestras arquitecturas es otra cosa desafiante porque necesitamos proporcionar una manera segura de comunicar nuestros servicios que son compatibles con cualquier tecnología que estemos usando y cualquiera que podamos usar en el futuro. Y no estamos hablando solo de Autenticación pura sino también de Autorización porque en una comunicación de servicio a servicio también necesitamos proporcionar una manera de verificar si el microservicio que está llamando a otro está permitido para hacerlo y hacerlo de una manera ágil para no detener todas las nuevas ventajas que su arquitectura nativa de la nube proporciona debido a su concepción.

Los requisitos de enrutamiento también han cambiado en estas nuevas arquitecturas. Si recuerdas cómo solíamos desplegar en arquitecturas tradicionales, normalmente intentamos encontrar un enfoque de cero tiempo de inactividad (cuando es posible) pero un procedimiento muy estándar. Desplegar una nueva versión, validar su funcionamiento y abrir el tráfico para cualquiera, pero hoy los requisitos exigen paradigmas mucho más complejos. Las tecnologías de Service Mesh soportan estrategias de implementación como Pruebas A/B, Enrutamiento basado en peso, Implementaciones Canary.

¿Rival o Compañero?

Entonces, después de hacer una vista rápida del propósito de estas tecnologías y el problema que intentaron resolver, ¿son rivales o compañeros? ¿Deberíamos elegir una u otra o intentar colocar ambas en nuestra arquitectura?

Como siempre, la respuesta a esas preguntas es la misma: «¡Depende!». Depende de lo que estás tratando de hacer, lo que tu empresa está tratando de lograr, lo que estás construyendo…

  • Se necesita una solución de Gestión de API siempre que estés implementando una Estrategia de API en tu organización. La tecnología de Service Mesh no está tratando de llenar ese vacío. Pueden proporcionar capacidades técnicas para cubrir lo que tradicionalmente ha hecho el componente de Gateway de API, pero este es solo uno de los elementos de la Solución de Gestión de API. Las otras partes que proporcionan las capacidades de gestión y gobernanza no están cubiertas por ningún Service Mesh hoy en día.
  • Se necesita Service Mesh si tienes una arquitectura nativa de la nube basada en la plataforma de contenedores que se basa firmemente en la comunicación HTTP para la comunicación sincrónica. Proporciona tantas capacidades técnicas que harán tu vida mucho más manejable que tan pronto como lo incluyas en tu arquitectura, no podrás vivir sin él.
  • Service Mesh solo va a proporcionar sus capacidades en un enfoque de plataforma de contenedores. Entonces, si tienes un panorama más heterogéneo como muchas empresas tienen hoy en día, (tienes una plataforma de contenedores pero también otras plataformas como aplicaciones SaaS, algunos sistemas aún en las instalaciones y arquitecturas tradicionales que todas ellas están proporcionando capacidades que te gustaría aprovechar como parte de los productos de API), necesitarás incluir una Solución de Gestión de API.

Por lo tanto, estas tecnologías pueden jugar juntas en una arquitectura completa para cubrir diferentes tipos de requisitos, especialmente cuando estamos hablando de arquitecturas heterogéneas complejas con la necesidad de incluir un enfoque Guiado por API.

En próximos artículos, cubriremos cómo podemos integrar ambas tecnologías desde el aspecto técnico y cómo fluye la información entre los diferentes componentes de la arquitectura.

Integración de Istio con aplicaciones BWCE

Integración de Istio con aplicaciones BWCE

Introducción

Service Mesh es una de las «nuevas grandes cosas» en nuestros entornos PaaS. No importa si estás trabajando con K8S, Docker Swarm, nube pura con EKS o AWS, has oído hablar y probablemente intentado saber cómo se puede usar esta nueva cosa que tiene tantas ventajas porque proporciona muchas opciones para manejar la comunicación entre componentes sin afectar la lógica de los componentes. Y si has oído hablar de Service Mesh, también has oído hablar de Istio, porque esta es la «opción insignia» en este momento, incluso cuando otras opciones como Linkerd o AWS App Mesh también son una gran opción, Istio es el Service Mesh más utilizado en este momento.

Probablemente hayas visto algunos ejemplos sobre cómo integrar Istio con tus desarrollos basados en código abierto, pero ¿qué pasa si tienes muchas aplicaciones BWCE o BusinessWorks… ¿puedes usar todo este poder? ¿O vas a ser excluido de este nuevo mundo?

¡No entres en pánico! Este artículo te va a mostrar lo fácil que puedes usar Istio con tu aplicación BWCE dentro de un clúster K8S. Así que, que comience el partido… ¡EMPIEZA!

Escenario

El escenario que vamos a probar es bastante simple. Es un enfoque simple de consumidor-proveedor. Vamos a usar un simple servicio web SOAP/HTTP expuesto por un backend para mostrar que esto puede funcionar no solo con API REST elegantes, sino incluso con cualquier tráfico HTTP que podamos generar a nivel de la aplicación BWCE.

Integración de Istio con aplicaciones BWCE

Así que, vamos a invocar un servicio que va a solicitar una respuesta de su proveedor y nos dará la respuesta. Eso es bastante fácil de configurar usando BWCE puro sin nada más.

Todo el código relacionado con este ejemplo está disponible para ti en el siguiente repositorio de GitHub: ¡Ve a buscar el código!

Pasos

Paso 1 Instalar Istio dentro de tu Clúster de Kubernetes

En mi caso, estoy usando un clúster de Kubernetes dentro de mi instalación de Docker Desktop, así que puedes hacer lo mismo o usar tu clúster de Kubernetes real, eso depende de ti. El primer paso de todos modos es instalar istio. Y para hacer eso, nada mejor que seguir los pasos dados en el taller de istio que puedes encontrar aquí: https://polarsquad.github.io/istio-workshop/install-istio/ (ACTUALIZACIÓN: Ya no disponible)

Una vez que hayas terminado, vamos a obtener el siguiente escenario en nuestro clúster de kubernetes, así que por favor, verifica que el resultado sea el mismo con los siguientes comandos:

kubectl get pods -n istio-system

Deberías ver que todos los pods están en ejecución como puedes ver en la imagen a continuación:

Integración de Istio con aplicaciones BWCE

kubectl -n istio-system get deployment -listio=sidecar-injector

Deberías ver que hay una instancia (CURRENT = 1) disponible.

Integración de Istio con aplicaciones BWCE

kubectl get namespace -L istio-injection

Deberías ver que ISTIO-INJECTION está habilitado para el espacio de nombres predeterminado como se muestra en la imagen a continuación:

Integración de Istio con aplicaciones BWCE

Paso 2 Construir Aplicaciones BWCE

Ahora, como tenemos toda la infraestructura necesaria a nivel de Istio, podemos comenzar a construir nuestra aplicación y para hacer eso no tenemos que hacer nada diferente en nuestra aplicación BWCE. Eventualmente, van a ser dos aplicaciones que se comunican usando HTTP como protocolo, así que nada específico.

Esto es algo importante porque cuando usualmente hablamos de Service Mesh e Istio con clientes, siempre surge la misma pregunta: ¿Es compatible Istio en BWCE? ¿Podemos usar Istio como un protocolo para comunicar nuestra aplicación BWCE? Así que, esperan que debería existir alguna paleta o algún complemento personalizado que deberían instalar para soportar Istio. Pero nada de eso es necesario a nivel de aplicación. Y eso se aplica no solo a BWCE sino también a cualquier otra tecnología como Flogo o incluso tecnologías de código abierto porque al final Istio (y Envoy es la otra parte necesaria en esta tecnología de la que usualmente evitamos hablar cuando hablamos de Istio) funciona en modo Proxy usando uno de los patrones más usuales en contenedores que es el «patrón sidecar«.

Así que, la tecnología que está exponiendo e implementando o consumiendo el servicio no sabe nada sobre toda esta «magia» que se está ejecutando en el medio de este proceso de comunicación.

Vamos a definir las siguientes propiedades como variables de entorno como lo haríamos en caso de que no estuviéramos usando Istio:

Aplicación del proveedor:

  • PROVIDER_PORT → Puerto donde el proveedor va a escuchar las solicitudes entrantes.

Aplicación del consumidor:

  • PROVIDER_PORT → Puerto donde el host del proveedor estará escuchando.
  • PROVIDER_HOST → Host o FQDN (también conocido como nombre del servicio K8S) donde se expondrá el servicio del proveedor.
  • CONSUMER_PORT → Puerto donde el servicio del consumidor va a escuchar las solicitudes entrantes.

Así que, como puedes ver si verificas que el código de la aplicación BWCE no necesitamos hacer nada especial para soportar Istio en nuestras aplicaciones BWCE.

NOTA: Solo hay un tema importante que no está relacionado con la integración de Istio, sino con cómo BWCE llena la propiedad BW.CLOUD.HOST que nunca se traduce a la interfaz de loopback o incluso 0.0.0.0. Así que es mejor que cambies esa variable por una personalizada o que uses localhost o 0.0.0.0 para escuchar en la interfaz de loopback porque es donde el proxy de Istio va a enviar las solicitudes.

Después de eso, vamos a crear nuestros Dockerfiles para estos servicios sin nada en particular, algo similar a lo que puedes ver aquí:

Integración de Istio con aplicaciones BWCE

NOTA: Como requisito previo, estamos usando la imagen base de Docker de BWCE llamada bwce_base.2.4.3 que corresponde a la versión 2.4.3 de BusinessWorks Container Edition.

Y ahora construimos nuestras imágenes de docker en nuestro repositorio como puedes ver en la siguiente imagen:

Integración de Istio con aplicaciones BWCE

Paso 3: Desplegar las Aplicaciones BWCE

Ahora, cuando todas las imágenes están siendo creadas, necesitamos generar los artefactos necesarios para desplegar estas aplicaciones en nuestro Clúster. Una vez más, en este caso, nada especial tampoco en nuestro archivo YAML, como puedes ver en la imagen a continuación, vamos a definir un servicio K8S y un despliegue K8S basado en la imagen que hemos creado en el paso anterior:

Integración de Istio con aplicaciones BWCE

Algo similar sucede con el despliegue del consumidor, como puedes ver en la imagen a continuación:

Integración de Istio con aplicaciones BWCE

Y podemos desplegarlos en nuestro clúster K8S con los siguientes comandos:

kubectl apply -f kube/provider.yaml

kubectl apply -f kube/consumer.yaml

Ahora, deberías ver los siguientes componentes desplegados. Solo para completar todos los componentes necesarios en nuestra estructura, vamos a crear un ingreso para hacer posible ejecutar solicitudes desde fuera del clúster a esos componentes y para hacer eso vamos a usar el siguiente archivo yaml:

kubectl apply -f kube/ingress.yaml

Y ahora, después de hacer eso, vamos a invocar el servicio dentro de nuestro proyecto SOAPUI y deberíamos obtener la siguiente respuesta:

Integración de Istio con aplicaciones BWCE

Paso 4 — Recapitular lo que acabamos de hacer

Ok, está funcionando y piensas… mmmm puedo hacer que esto funcione sin Istio y no sé si Istio todavía está haciendo algo o no…

Ok, tienes razón, esto podría no ser tan genial como esperabas, pero, créeme, solo estamos yendo paso a paso… Veamos qué está realmente sucediendo en lugar de una simple solicitud desde fuera del clúster al servicio del consumidor y esa solicitud siendo reenviada al backend, lo que está sucediendo es un poco más complejo. Echemos un vistazo a la imagen a continuación:

Integración de Istio con aplicaciones BWCE

La solicitud entrante desde el exterior está siendo manejada por un Controlador de Ingreso Envoy que va a ejecutar todas las reglas definidas para elegir qué servicio debe manejar la solicitud, en nuestro caso el único componente consumer-v1 lo va a hacer, y lo mismo sucede en la comunicación entre consumidor y proveedor.

Así que, estamos obteniendo algunos interceptores en el medio que PODRÍAN aplicar la lógica que nos va a ayudar a enrutar el tráfico entre nuestros componentes con el despliegue de reglas a nivel de tiempo de ejecución sin cambiar la aplicación, y esa es la MAGIA.

Paso 5 — Implementar Lanzamiento Canary

Ok, ahora apliquemos algo de esta magia a nuestro caso. Uno de los patrones más usuales que solemos aplicar cuando estamos implementando una actualización en algunos de nuestros servicios es el enfoque canary. Solo para hacer una explicación rápida de lo que es esto:

El lanzamiento canary es una técnica para reducir el riesgo de introducir una nueva versión de software en producción al implementar lentamente el cambio a un pequeño subconjunto de usuarios antes de implementarlo en toda la infraestructura y hacerlo disponible para todos.

Integración de Istio con aplicaciones BWCE

Si quieres leer más sobre esto, puedes echar un vistazo al artículo completo en el blog de Martin Fowler.

Así que, ahora vamos a generar un pequeño cambio en nuestra aplicación del proveedor, que va a cambiar la respuesta para asegurarnos de que estamos apuntando a la versión dos, como puedes ver en la imagen a continuación:

Integración de Istio con aplicaciones BWCE

Ahora, vamos a construir esta aplicación y generar la nueva imagen llamada provider:v2.

Pero antes vamos a desplegarla usando el archivo YAML llamado provider-v2.yaml, vamos a establecer una regla en nuestro Service Mesh de Istio de que todo el tráfico debe dirigirse a v1 incluso cuando otros se apliquen. Para hacer eso, vamos a desplegar el archivo llamado default.yaml que tiene el siguiente contenido:

Integración de Istio con aplicaciones BWCE

Así que, en este caso, lo que le estamos diciendo a Istio es que incluso si hay otros componentes registrados en el servicio, siempre debe responder el v1, por lo que ahora podemos desplegar el v2 sin ningún problema porque no va a responder a ningún tráfico hasta que decidamos hacerlo. Así que, ahora podemos desplegar el v2 con el siguiente comando:

kubectl apply -f provider-v2.yaml

Y aunque ejecutemos la solicitud SOAPUI, todavía estamos obteniendo una respuesta v1 incluso si verificamos en la configuración del servicio K8S que el v2 todavía está vinculado a ese servicio.

Ok, ahora vamos a comenzar a hacer el lanzamiento y vamos a comenzar con el 10% a la nueva versión y el 90% de las solicitudes a la antigua, y para hacer eso vamos a desplegar la regla canary.yaml usando el siguiente comando:

kubectl apply -f canary.yaml

Donde canary.yaml tiene el contenido que se muestra a continuación:

Integración de Istio con aplicaciones BWCE

Y ahora, cuando intentemos suficientes veces, vamos a obtener que la mayoría de las solicitudes (aproximadamente el 90%) van a responder v1 y solo el 10% va a responder desde mi nueva versión:

Integración de Istio con aplicaciones BWCE

Ahora, podemos monitorear cómo está funcionando v2 sin afectar a todos los clientes y si todo va como se espera, podemos continuar aumentando ese porcentaje hasta que todos los clientes estén siendo respondidos por v2.