Implementación de Canary en Kubernetes #3: Istio

Uso de Istio+Kiali para implementar y visualizar despliegues Canary

Implementación de Canary en Kubernetes #3: Istio

Artículos de este ciclo

  1. Despliegue Canary en Kubernetes #1: Gitlab CI
  2. Implementación Canary en Kubernetes #2: Argo Rollouts
  3. (este artículo)
  4. Despliegue Canary usando Jenkins-X Istio Flagger

Despliegue Canary

Esperamos que hayas leído la primera parte, donde explicamos brevemente qué son los despliegues Canary y mostramos cómo implementarlo utilizando recursos estándar de Kubernetes.

Istio

Y suponemos que al leer este artículo, ya sabes qué es Istio. Si no, puedes leer sobre él aquí.

Aplicación para pruebas

Implementación de Canary en Kubernetes #3: Istio

Cada pod contiene dos contenedores: nuestra aplicación e istio-proxy.

Usaremos una aplicación de prueba simple con pods frontend-nginx y backend en python. El pod con nginx simplemente redirigirá cada solicitud al pod con backend y funcionará como un proxy. Los detalles pueden verse más adelante en los siguientes archivos yaml:

Ejecutar la aplicación de prueba por tu cuenta

Si deseas seguir mi ejemplo y usar esta aplicación de prueba por tu cuenta, consulta el readme del proyecto.

Despliegue inicial

Al iniciar el primer despliegue, vemos que los pods de nuestra aplicación tienen solo 2 contenedores, es decir, el sidecar de Istio aún se está implementando:

Implementación de Canary en Kubernetes #3: Istio

Y también vemos el Loadbalancer de Istio Gateway en el namespace istio-system:

Implementación de Canary en Kubernetes #3: Istio

Generación de tráfico

Usaremos la siguiente IP para generar tráfico que será recibido por los pods de frontend y redirigido a los pods de backend:

while true; do curl -s --resolve 'frontend.istio-test:80:35.242.202.152' frontend.istio-test; sleep 0.1; done

También añadiremos frontend.istio-test a nuestro archivo hosts.

Visualización de Mesh a través de Kiali

Hemos instalado la aplicación de prueba e Istio junto con Tracing, Grafana, Prometheus y Kiali (ver más en el readme del proyecto). Por lo tanto, podemos usar Kiali a través de:

istioctl dashboard kiali # admin:admin

Implementación de Canary en Kubernetes #3: Istio

Kiali visualiza el tráfico actual a través de Mesh

Como vemos, el 100% del tráfico llega al servicio frontend, luego al pod del frontend con la etiqueta v1, ya que utilizamos un proxy nginx simple que redirige las solicitudes al servicio backend, que a su vez las redirige a los pods de backend con la etiqueta v1.

Kiali funciona excelente junto con Istio y proporciona una solución lista para la visualización de Mesh. Es simplemente maravilloso.

Despliegue Canary

Nuestro backend ya tiene dos despliegues k8s, uno para v1 y otro para v2. Ahora solo necesitamos decirle a Istio que redirija un cierto porcentaje de solicitudes a v2.

Paso 1: 10%

Y todo lo que necesitamos hacer es ajustar el peso de VirtualService en istio.yaml:

apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
  name: backend
  namespace: default
spec:
  gateways: []
  hosts:
  - "backend.default.svc.cluster.local"
  http:
  - match:
    - {}
    route:
    - destination:
        host: backend.default.svc.cluster.local
        subset: v1
        port:
          number: 80
      weight: 90
    - destination:
        host: backend.default.svc.cluster.local
        subset: v2
        port:
          number: 80
      weight: 10

Implementación de Canary en Kubernetes #3: Istio

Vemos que el 10% de las solicitudes se redirige a v2.

Paso 2: 50%

Y ahora, simplemente hay que aumentarlo al 50%:

apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
  name: backend
  namespace: default
spec:
...
    - destination:
        host: backend.default.svc.cluster.local
        subset: v1
        port:
          number: 80
      weight: 50
    - destination:
        host: backend.default.svc.cluster.local
        subset: v2
        port:
          number: 80
      weight: 50

Implementación de Canary en Kubernetes #3: Istio

Paso 3: 100%

Ahora el despliegue Canary se considera completo y todo el tráfico se redirige a v2:

Implementación de Canary en Kubernetes #3: Istio

Pruebas manuales de Canary

Supongamos que ahora estamos enviando el 10% de todas las solicitudes al backend v2. ¿Qué pasa si queremos probar manualmente el v2 para asegurarnos de que todo funciona como esperamos?

Podemos añadir una regla de coincidencia especial basada en los encabezados HTTP:

apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
  name: backend
  namespace: default
spec:
  gateways: []
  hosts:
  - "backend.default.svc.cluster.local"
  http:
  - match:
    - headers:
        canary:
          exact: "canary-tester"
    route:
    - destination:
        host: backend.default.svc.cluster.local
        subset: v2
        port:
          number: 80
      weight: 100
  - match:
    - {}
    route:
    - destination:
        host: backend.default.svc.cluster.local
        subset: v1
        port:
          number: 80
      weight: 90
    - destination:
        host: backend.default.svc.cluster.local
        subset: v2
        port:
          number: 80
      weight: 10

Ahora, usando curl, podemos forzar una solicitud a v2 enviando el encabezado:

Implementación de Canary en Kubernetes #3: Istio

Las solicitudes sin encabezado aún serán manejadas en la proporción 1/10:

Implementación de Canary en Kubernetes #3: Istio

Canary para dos versiones dependientes

Ahora consideraremos el caso en el que tenemos la versión v2 tanto para el frontend como para el backend. Para ambos hemos especificado que el 10% del tráfico debe ir a v2:

Implementación de Canary en Kubernetes #3: Istio

Vemos que el frontend v1 y v2 redirigen tráfico en una proporción de 1/10 a los backend v1 y v2.

¿Y si necesitáramos redirigir el tráfico de frontend-v2 solo a backend-v2, porque no es compatible con v1? Para ello, estableceremos una proporción de 1/10 para el frontend, que controla qué tráfico llega a backend-v2 utilizando la coincidencia por sourceLabels :

apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
  name: backend
  namespace: default
spec:
  gateways: []
  hosts:
  - "backend.default.svc.cluster.local"
  http:
...
  - match:
    - sourceLabels:
        app: frontend
        version: v2
    route:
    - destination:
        host: backend.default.svc.cluster.local
        subset: v2
        port:
          number: 80
      weight: 100

Como resultado, obtenemos lo que necesitamos:

Implementación de Canary en Kubernetes #3: Istio

Diferencias con el enfoque manual de Canary

En parte anterior realizábamos el despliegue de Canary manualmente, utilizando también dos despliegues de k8s. Allí gestionábamos la proporción de solicitudes, cambiando el número de réplicas. Este enfoque funciona, pero tiene serias desventajas.

Istio permite definir la proporción de solicitudes independientemente del número de réplicas. Esto significa, por ejemplo, que podemos utilizar HPAs (Horizontal Pod Autoscalers — escalado horizontal de pods) y no es necesario configurarlo de acuerdo con el estado actual del despliegue de Canary.

Summary

Istio funciona excelente y al usarlo junto con Kiali obtenemos una combinación muy poderosa. Lo siguiente en mi lista de intereses es la combinación de Spinnaker con Istio para la automatización y análisis de Canary.

Fuente: habr.com

Compra un hosting fiable para sitios web con protección contra DDoS, servidores VPS VDS 🔥 Compra un hosting fiable para sitios web con protección contra DDoS, servidores VPS VDS | ProHoster