Uso de Istio+Kiali para iniciar y visualizar una implementación de Canary

Artículos de esta serie
- (Este artículo)
- Implementación de Canary utilizando Jenkins-X Istio Flagger
Implementación canaria
Esperamos que leas , donde explicamos brevemente qué son las implementaciones de Canary y mostramos cómo implementarlas utilizando recursos estándar de Kubernetes.
Istio
Y suponemos que leyendo este artículo ya sabes qué es Istio. Si no, entonces puedes leer sobre ello. .
Solicitud de pruebas

Cada pod contiene dos contenedores: nuestra aplicación e istio-proxy.
Usaremos una aplicación de prueba simple con pods de Python frontend-nginx y backend. El pod nginx simplemente redirigirá cada solicitud al pod de backend y funcionará como un proxy. Los detalles se pueden encontrar en los siguientes yamls:
Ejecutar la aplicación de prueba usted mismo
Si desea seguir mi ejemplo y utilizar esta aplicación de prueba usted mismo, consulte .
Implementación inicial
Cuando lanzamos el primer Deployment, vemos que los pods de nuestra aplicación tienen solo 2 contenedores, es decir, el sidecar de Istio recién se está implementando:

Y también vemos Istio Gateway Loadbalancer en el espacio de nombres. istio-system:

Generación de tráfico
Usaremos la siguiente IP para generar tráfico que será recibido por los pods de frontend y reenviado 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 agregaremos frontend.istio-test a nuestro archivo de hosts.
Ver malla a través de Kiali
Instalamos la aplicación de prueba e Istio junto con Tracing, Grafana, Prometheus y Kiali (consulte los detalles a continuación). ). Por tanto podemos utilizar Kiali a través de:
istioctl dashboard kiali # admin:admin

Kiali visualiza el tráfico actual a través de Mesh
Como podemos ver, el 100% del tráfico va al servicio frontend, luego a los pods frontend con etiqueta v1, ya que estamos usando un proxy nginx simple que redirige las solicitudes al servicio backend, que a su vez las redirige a los pods backend. con etiqueta v1.
Kiali funciona muy bien con Istio y proporciona una solución de renderizado Mesh en caja. Simplemente genial.
Implementación canaria
Nuestro backend ya tiene dos implementaciones de k8, una para v1 y otra para v2. Ahora solo necesitamos decirle a Istio que reenvíe un cierto porcentaje de solicitudes a v2.
Paso 1: 10%
Y todo lo que tenemos que hacer es ajustar el peso del VirtualService en :
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 
Vemos que el 10% de las solicitudes se redirigen a la v2.
Paso 2: 50%
Y ahora basta con 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 
Paso 3: 100%
Ahora la implementación de Canary se puede considerar completa y todo el tráfico se redirige a la versión 2:

Probar Canary manualmente
Digamos que ahora enviamos el 2% de todas las solicitudes al backend v10. ¿Qué pasa si queremos probar manualmente la v2 para asegurarnos de que todo funcione como esperamos?
Podemos agregar una regla de coincidencia especial basada en 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: 10Ahora usando curl podemos forzar una solicitud v2 enviando el encabezado:
![]()
Las solicitudes sin encabezado seguirán siendo impulsadas por la proporción 1/10:

Canary para dos versiones dependientes
Ahora consideraremos la opción donde tenemos la versión v2 tanto para el frontend como para el backend. Para ambos, especificamos que el 10% del tráfico debería dirigirse a la versión 2:

Vemos que tanto el frontend v1 como el v2 reenvían el tráfico en una proporción de 1/10 al backend v1 y v2.
¿Qué pasaría si necesitáramos reenviar el tráfico desde frontend-v2 solo a backend-v2 porque no es compatible con v1? Para hacer esto, estableceremos una proporción de 1/10 para el frontend, que controla qué tráfico llega al backend-v2 mediante negociación. 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: 100Como resultado, obtenemos lo que necesitamos:

Diferencias con el enfoque canario manual
В la primera parte Realizamos la implementación de Canary manualmente, también usando dos implementaciones de k8. Allí controlamos la proporción de solicitudes cambiando la cantidad de réplicas. Este enfoque funciona, pero tiene serios inconvenientes.
Istio permite determinar la proporción de solicitudes independientemente del número de réplicas. Esto significa, por ejemplo, que podemos usar HPA (Horizontal Pod Autoscalers) y no es necesario configurarlos de acuerdo con el estado actual de la implementación de Canary.
Total
Istio funciona muy bien y usarlo junto con Kiali crea una combinación muy poderosa. El siguiente en mi lista de intereses es combinar Spinnaker con Istio para la automatización y el análisis Canary.
Fuente: habr.com
