Seguimos explorando Istio y sus funcionalidades


Introducción

Este artículo se basa en lo que hicimos en el artículo anterior, así que consúltalo antes de comenzar este. Si planeas seguir los ejemplos de la documentación, encontrarás muchas similitudes ya que basé este artículo en eso.


En este ejemplo usaré Digital Ocean (ese es mi enlace de referido). Ten en cuenta que no tengo ninguna asociación con Digital Ocean, pero te dan $100 para probar sus productos durante 60 días; si gastas $25, yo obtengo otros $25.


Antes de comenzar, algunos conceptos

  • Un VirtualService define las reglas que controlan cómo se enrutan las solicitudes para un servicio dentro de un service mesh de Istio.
  • Un DestinationRule configura el conjunto de políticas que se aplicarán a una solicitud después de que haya ocurrido el enrutamiento de VirtualService.
  • Un ServiceEntry se usa comúnmente para habilitar solicitudes a servicios fuera de un service mesh de Istio.
  • Un Gateway configura un balanceador de carga para tráfico HTTP/TCP, operando más comúnmente en el borde del mesh para habilitar el tráfico de entrada para una aplicación.

Estos conceptos básicos te ayudarán a entender el manifiesto que vamos a ver.


Empecemos

Ya tenemos el proyecto bookinfo desplegado y utilizando las tres versiones del servicio (ratings), pero necesitaremos hacer algunos cambios para probar el enrutamiento basado en la identidad del usuario. Puedes comprobar la configuración con:

$ kubectl get destinationrules -o yaml
apiVersion: v1
items:
- apiVersion: networking.istio.io/v1alpha3
  kind: DestinationRule
  metadata:
    annotations:
      kubectl.kubernetes.io/last-applied-configuration: |
        {"apiVersion":"networking.istio.io/v1alpha3","kind":"DestinationRule","metadata":{"annotations":{},"name":"details","namespace":"default"},"spec":{"host":"details","subsets":[{"labels":{"version":"v1"},"name":"v1"},{"labels":{"version":"v2"},"name":"v2"}]}}
    creationTimestamp: 2019-01-11T00:58:54Z
    generation: 1
    name: details
    namespace: default
    resourceVersion: "921688"
    selfLink: /apis/networking.istio.io/v1alpha3/namespaces/default/destinationrules/details
    uid: 11490656-153c-11e9-9eda-6a85233ec1d5
  spec:
    host: details
    subsets:
    - labels:
        version: v1
      name: v1
    - labels:
        version: v2
      name: v2
- apiVersion: networking.istio.io/v1alpha3
  kind: DestinationRule
  metadata:
    annotations:
      kubectl.kubernetes.io/last-applied-configuration: |
        {"apiVersion":"networking.istio.io/v1alpha3","kind":"DestinationRule","metadata":{"annotations":{},"name":"productpage","namespace":"default"},"spec":{"host":"productpage","subsets":[{"labels":{"version":"v1"},"name":"v1"}]}}
    creationTimestamp: 2019-01-11T00:58:53Z
    generation: 1
    name: productpage
    namespace: default
    resourceVersion: "921684"
    selfLink: /apis/networking.istio.io/v1alpha3/namespaces/default/destinationrules/productpage
    uid: 10a42a24-153c-11e9-9eda-6a85233ec1d5
  spec:
    host: productpage
    subsets:
    - labels:
        version: v1
      name: v1
- apiVersion: networking.istio.io/v1alpha3
  kind: DestinationRule
  metadata:
    annotations:
      kubectl.kubernetes.io/last-applied-configuration: |
        {"apiVersion":"networking.istio.io/v1alpha3","kind":"DestinationRule","metadata":{"annotations":{},"name":"ratings","namespace":"default"},"spec":{"host":"ratings","subsets":[{"labels":{"version":"v1"},"name":"v1"},{"labels":{"version":"v2"},"name":"v2"},{"labels":{"version":"v2-mysql"},"name":"v2-mysql"},{"labels":{"version":"v2-mysql-vm"},"name":"v2-mysql-vm"}]}}
    creationTimestamp: 2019-01-11T00:58:54Z
    generation: 1
    name: ratings
    namespace: default
    resourceVersion: "921686"
    selfLink: /apis/networking.istio.io/v1alpha3/namespaces/default/destinationrules/ratings
    uid: 111299e1-153c-11e9-9eda-6a85233ec1d5
  spec:
    host: ratings
    subsets:
    - labels:
        version: v1
      name: v1
    - labels:
        version: v2
      name: v2
    - labels:
        version: v2-mysql
      name: v2-mysql
    - labels:
        version: v2-mysql-vm
      name: v2-mysql-vm
- apiVersion: networking.istio.io/v1alpha3
  kind: DestinationRule
  metadata:
    annotations:
      kubectl.kubernetes.io/last-applied-configuration: |
        {"apiVersion":"networking.istio.io/v1alpha3","kind":"DestinationRule","metadata":{"annotations":{},"name":"reviews","namespace":"default"},"spec":{"host":"reviews","subsets":[{"labels":{"version":"v1"},"name":"v1"},{"labels":{"version":"v2"},"name":"v2"},{"labels":{"version":"v3"},"name":"v3"}]}}
    creationTimestamp: 2019-01-11T00:58:53Z
    generation: 1
    name: reviews
    namespace: default
    resourceVersion: "921685"
    selfLink: /apis/networking.istio.io/v1alpha3/namespaces/default/destinationrules/reviews
    uid: 10db9ee2-153c-11e9-9eda-6a85233ec1d5
  spec:
    host: reviews
    subsets:
    - labels:
        version: v1
      name: v1
    - labels:
        version: v2
      name: v2
    - labels:
        version: v3
      name: v3
kind: List
metadata:
  resourceVersion: ""
  selfLink: ""

Ahí tenemos todas las reglas de destino, y ahora necesitamos aplicar el nuevo manifiesto que enviará todo a la versión 1 y al usuario jason a la versión 2 del microservicio reviews.


istio-1.0.5/samples/bookinfo $ kubectl apply -f networking/virtual-service-reviews-test-v2.yaml
virtualservice.networking.istio.io "reviews" created

$ kubectl get virtualservice reviews -o yaml
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
  annotations:
    kubectl.kubernetes.io/last-applied-configuration: |
      {"apiVersion":"networking.istio.io/v1alpha3","kind":"VirtualService","metadata":{"annotations":{},"name":"reviews","namespace":"default"},"spec":{"hosts":["reviews"],"http":[{"match":[{"headers":{"end-user":{"exact":"jason"}}}],"route":[{"destination":{"host":"reviews","subset":"v2"}}]},{"route":[{"destination":{"host":"reviews","subset":"v1"}}]}]}}
  creationTimestamp: 2019-01-11T02:30:35Z
  generation: 1
  name: reviews
  namespace: default
  resourceVersion: "930577"
  selfLink: /apis/networking.istio.io/v1alpha3/namespaces/default/virtualservices/reviews
  uid: e0701f0d-1548-11e9-9eda-6a85233ec1d5
spec:
  hosts:
  - reviews
  http:
  - match:
    - headers:
        end-user:
          exact: jason
    route:
    - destination:
        host: reviews
        subset: v2
  - route:
    - destination:
        host: reviews
        subset: v1

¿Qué está pasando aquí? ¿Cómo sabe Istio qué usuario ha iniciado sesión? Bueno, la aplicación añade un encabezado llamado end-user con el valor jason; entonces se usará la ruta. Es un truco ingenioso.


No jason:

img


jason:

img

Como puedes ver, la diferencia entre la versión 1 y la versión 2 de la aplicación son las estrellas debajo de las reseñas, pero eso es más que suficiente para indicar que funciona. Esto es realmente útil para los beta testers; no necesitas complicar tu código, solo agregar un encabezado.


Inyectando una falla HTTP abort

Esta vez inyectaremos una falla para nuestro amigo jason:

istio-1.0.5/samples/bookinfo $ kubectl apply -f networking/virtual-service-ratings-test-abort.yaml
virtualservice.networking.istio.io "ratings" created

$ kubectl get virtualservice ratings -o yaml
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
  annotations:
    kubectl.kubernetes.io/last-applied-configuration: |
      {"apiVersion":"networking.istio.io/v1alpha3","kind":"VirtualService","metadata":{"annotations":{},"name":"ratings","namespace":"default"},"spec":{"hosts":["ratings"],"http":[{"fault":{"abort":{"httpStatus":500,"percent":100}},"match":[{"headers":{"end-user":{"exact":"jason"}}}],"route":[{"destination":{"host":"ratings","subset":"v1"}}]},{"route":[{"destination":{"host":"ratings","subset":"v1"}}]}]}}
  creationTimestamp: 2019-01-11T02:50:59Z
  generation: 1
  name: ratings
  namespace: default
  resourceVersion: "932552"
  selfLink: /apis/networking.istio.io/v1alpha3/namespaces/default/virtualservices/ratings
  uid: b98799b0-154b-11e9-9eda-6a85233ec1d5
spec:
  hosts:
  - ratings
  http:
  - fault:
      abort:
        httpStatus: 500
        percent: 100
    match:
    - headers:
        end-user:
          exact: jason
    route:
    - destination:
        host: ratings
        subset: v1
  - route:
    - destination:
        host: ratings
        subset: v1

Así que decidió revisar las reseñas de libros nuevamente y ¡boom!, el servicio de calificaciones no estaba disponible, pero todo lo demás funciona perfectamente. Esto solo se aplica a jason; todos los demás verán la versión sin estrellas o el mensaje de error.

img


Notas

Istio parece y de hecho es realmente poderoso. Hay muchas más características como:

  • Cambio de tráfico.
  • Tiempos de espera de solicitudes.
  • Circuit breaking.
  • Mirroring.
  • Y mucho más.

Dejé de lado Políticas, Telemetría y Seguridad. Si deseas aprender más sobre Istio, te recomiendo encarecidamente que pruebes los ejemplos tú mismo y leas la documentación oficial.


También dediqué algo de tiempo a mejorar la navegación del blog y otros detalles menores, pero quería mantener los artículos en marcha, por eso este es tan simple y similar a la documentación.


Próximos temas e ideas

Quiero comenzar a crear series de contenido sobre diferentes temas, artículos breves que puedan ayudarte a comenzar con alguna nueva tecnología o tal vez darte una idea de cómo funciona. Déjame saber si estás interesado en ese tipo de contenido en los comentarios o vía Twitter 🐦 (es un pájaro, en caso de que no puedas ver caracteres Unicode).


Errata

Si encuentras algún error o tienes alguna sugerencia, por favor envíame un mensaje para que pueda corregirlo.



No tienes cuenta? Regístrate aqui

Ya registrado? Iniciar sesión a tu cuenta ahora.

Iniciar session con GitHub
Iniciar sesion con Google
  • Comentarios

    Online: 0

Por favor inicie sesión para poder escribir comentarios.

by Gabriel Garrido