Kubernetes: Istio Traffic Management

Ismael Chasco
Nov 17 · 5 min read

Buenas, hoy hablaremos de la gestión de tráfico con Istio sobre Kubernetes. En anteriores posts, ya hablamos de como desplegar Istio. Y ahora toca poner en práctica lo que se puede hacer.

Para ello, vamos a utilizar imágenes de docker muy simples que son un Nginx con un HTML que muestra o versión 1 o versión 2 dependiendo el tag que se aplique en el Deployment. También usaremos nip.io para crear los DNSs y siege para hacer pruebas de carga y ver los resultados.

Los ficheros que vamos a utilizar, están en este repo:
https://github.com/ichasco/Istio-traffic-management

Let’s Go!

Traffic Split

El Traffic Split o comúnmente denominado Canary, es dividir el tráfico entre diferentes versiones de una aplicación, de una forma controlada. Esto nos vale en el caso de desplegar una versión nueva, para poder comprobar sobre un pequeño porcentaje, que no haya errores. Y una vez comprobado, hacer que todo el tráfico vaya a la nueva versión.

En Istio, el traffic split, se hace por pesos (weights). Hay que definir en el VirtualService el balanceo de tráfico que queremos y aplicarlo por subsets. Una vez hecho esto, se definen los subsets en el DestinationRule con las labels del Deployment y ya estaría.

A continuación lo explico con un ejemplo:

Deployment

En el Deployment, vamos a desplegar PODs con diferentes versiones de contenedor. Lo importante en este caso, es definir el spec.template.metadata.version con la versión correcta.

---
apiVersion: apps/v1
kind: Deployment
metadata:
name: traffic-split-v1
namespace: istio-poc
labels:
app: traffic-split
spec:
replicas: 1
selector:
matchLabels:
app: traffic-split
template:
metadata:
labels:
app: traffic-split
version: v1
spec:
containers:
- name: traffic-split
image: ichasco/test-app:v1
imagePullPolicy: Always

---
apiVersion: apps/v1
kind: Deployment
metadata:
name: traffic-split-v2
namespace: istio-poc
labels:
app: traffic-split
spec:
replicas: 1
selector:
matchLabels:
app: traffic-split
template:
metadata:
labels:
app: traffic-split
version: v2
spec:
containers:
- name: traffic-split
image: ichasco/test-app:v2
imagePullPolicy: Always

Service

El Service no tiene nada especial. Lo único que se hace es definir el puerto y a que aplicación aplica.

---
kind: Service
apiVersion: v1
metadata:
name: traffic-split
namespace: istio-poc
labels:
app: traffic-split
spec:
selector:
app: traffic-split
type: ClusterIP
ports:
- name: http
port: 80

VirtualService

En el VirtualService, tenemos que definir tanto el host, como los pesos que tendrán las aplicaciones.

---
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: traffic-split
namespace: istio-poc
spec:
hosts:
- traffic-split.104.155.93.105.nip.io
gateways:
- istio-poc
http:
- name: traffic-split
match:
- uri:
prefix: /
route:
- destination:
host: traffic-split
subset: v1
weight: 80
- destination:
host: traffic-split
subset: v2
weight: 20

DestinationRule

Aquí tenemos que definir los subsets que hemos aplicado en el VirtualService.

---
apiVersion: networking.istio.io/v1alpha3
kind: DestinationRule
metadata:
name: traffic-split
spec:
host: traffic-split
subsets:
- name: v1
labels:
version: v1
- name: v2
labels:
version: v2

Prueba

Para probar esto, vamos a lanzar un test de carga con la herramienta siege y veremos los resultados en Kiali.

siege -c 5 -r 1000 http://traffic-split.35.240.106.245.nip.io/

Como se puede observar, se está dividiendo el tráfico en un 80/20 sobre las versiones de la aplicación.

Traffic Header Rules

En Istio, cuando se le quiere dar algo de lógica al tráfico, poner condiciones, establecer pesos… se utilizan los VirtualServices. En este ejemplo, vamos a hacer que el tráfico que vaya desde un user-agent (Firefox) vaya contra la versión 1 y lo que vaya con otro (curl), vaya a la versión 2. Esto se puede extrapolar a por ejemplo, discriminación de sistemas operativos; Linux/Windows, Android/iOS… O también si alguna de las headers de la petición trae algún parámetro en concreto; localización, usuario…

Para hacer esto, hay que cambiar el VirtualService

http:
- match:
- headers:
user-agent:
regex: '.*Firefox.*'
route:
- destination:
host: traffic-rule
subset: v1
- match:
- headers:
user-agent:
regex: '.*curl.*'
route:
- destination:
host: traffic-rule
subset: v2

Ahora para probar que funciona, vamos a lanzar un curl con los diferentes user-agents

curl -A Firefox traffic-rule.104.155.93.105.nip.ioVersion 1curl traffic-rule.104.155.93.105.nip.ioVersion 2

Traffic Mirroring

Esta técnica, es bastante efectiva si no estamos seguros de que la nueva versión que queremos desplegar, vaya a funcionar y no queremos ninguna pérdida de servicios. Esto lo que hace, es hacer un mirror de todo el tráfico.

Vamos a empezar mandando todo el tráfico a la versión 1 para ver que todo va bien. Y haremos que el mismo tráfico que va la V1, vaya a la V2 y revisaremos los logs.

Para esto, solo hay que cambiar en el VirtualService lo siguiente:

route:
- destination:
host: traffic-mirror
subset: v1
weight: 100

Y el resultado sería

Como se puede ver, todo el tráfico está yendo contra la v1. Ahora vamos a hacer que se replique contra el v2.

Para hacer esto, hay que volver a cambiar el VirtualService y dejarlo de la siguiente manera:

route:
- destination:
host: traffic-mirror
subset: v1
weight: 100
mirror:
host: traffic-mirror
subset: v2
mirror_percent: 100

Como se puede ver, el tráfico sigue yendo contra la v1, pero la v2 se ha puesto como mirror. Y de este modo, podemos comprobar todos los logs de esta versión y ver si hay algún error.

Troubleshooting

Si se activa el mTLS, hay que configurar en el DestinationRule para que lo soporte.

spec:
host: traffic-split
trafficPolicy:
tls:
mode: ISTIO_MUTUAL

Como se puede ver, es bastante fácil jugar con la red. Además de esto, se pueden controlar varios factores mas como; Fault Injection, Request Timeout, Circuit Breaking… Abstrayendonos de la aplicación y configurándolo directamente en Istio.


Originally published at blog.ichasco.com.

Welcome to a place where words matter. On Medium, smart voices and original ideas take center stage - with no ads in sight. Watch
Follow all the topics you care about, and we’ll deliver the best stories for you to your homepage and inbox. Explore
Get unlimited access to the best stories on Medium — and support writers while you’re at it. Just $5/month. Upgrade