Exercise 3: Manage Traffic with Istio
In this exercise, you will expose the demo application through the Istio ingress gateway and use Istio routing rules to shift traffic between the two application versions.
Info
This exercise uses an Istio Gateway because we are exposing the application to traffic from outside the cluster. The traffic splitting itself is done by the VirtualService and DestinationRule, which would also work for service-to-service traffic inside the mesh without any gateway. The Gateway is only here to provide an external entry point so you can reach the app from your browser - it is not a requirement of traffic management.
Task 1: Create Istio Routing Resources
Create an Istio
Gateway,DestinationRule, andVirtualService.@" apiVersion: networking.istio.io/v1beta1 kind: Gateway metadata: name: web-gateway namespace: istio-demo spec: selector: istio: aks-istio-ingressgateway-external servers: - port: number: 80 name: http protocol: HTTP hosts: - "*" --- apiVersion: networking.istio.io/v1beta1 kind: DestinationRule metadata: name: web namespace: istio-demo spec: host: web subsets: - name: v1 labels: version: v1 - name: v2 labels: version: v2 --- apiVersion: networking.istio.io/v1beta1 kind: VirtualService metadata: name: web namespace: istio-demo spec: hosts: - "*" gateways: - web-gateway http: - route: - destination: host: web subset: v1 weight: 80 - destination: host: web subset: v2 weight: 20 "@ | kubectl apply -f -cat <<EOF | kubectl apply -f - apiVersion: networking.istio.io/v1beta1 kind: Gateway metadata: name: web-gateway namespace: istio-demo spec: selector: istio: aks-istio-ingressgateway-external servers: - port: number: 80 name: http protocol: HTTP hosts: - "*" --- apiVersion: networking.istio.io/v1beta1 kind: DestinationRule metadata: name: web namespace: istio-demo spec: host: web subsets: - name: v1 labels: version: v1 - name: v2 labels: version: v2 --- apiVersion: networking.istio.io/v1beta1 kind: VirtualService metadata: name: web namespace: istio-demo spec: hosts: - "*" gateways: - web-gateway http: - route: - destination: host: web subset: v1 weight: 80 - destination: host: web subset: v2 weight: 20 EOF
Task 2: Test the Traffic Split
Get the public IP address for the Istio ingress gateway.
$INGRESS_IP = kubectl get service aks-istio-ingressgateway-external ` -n aks-istio-ingress ` -o jsonpath="{.status.loadBalancer.ingress[0].ip}" Write-Host "http://$INGRESS_IP"INGRESS_IP=$(kubectl get service aks-istio-ingressgateway-external \ -n aks-istio-ingress \ -o jsonpath="{.status.loadBalancer.ingress[0].ip}") echo "http://$INGRESS_IP"Send repeated requests and observe the traffic split between versions.
1..20 | ForEach-Object { Invoke-WebRequest -UseBasicParsing "http://$INGRESS_IP" | Select-Object -ExpandProperty Content }for i in {1..20}; do curl -s "http://$INGRESS_IP" | grep -E "Hello|Version|Hostname" || true doneMost responses should come from v1, with some responses from v2. This is controlled by the
80/20weights in theVirtualService.
Task 3: Shift All Traffic to v2
Update the
VirtualServiceto send all traffic to v2.@" apiVersion: networking.istio.io/v1beta1 kind: VirtualService metadata: name: web namespace: istio-demo spec: hosts: - "*" gateways: - web-gateway http: - route: - destination: host: web subset: v2 weight: 100 "@ | kubectl apply -f -cat <<EOF | kubectl apply -f - apiVersion: networking.istio.io/v1beta1 kind: VirtualService metadata: name: web namespace: istio-demo spec: hosts: - "*" gateways: - web-gateway http: - route: - destination: host: web subset: v2 weight: 100 EOFTest the application again. All responses should now be served by v2.
1..10 | ForEach-Object { Invoke-WebRequest -UseBasicParsing "http://$INGRESS_IP" | Select-Object -ExpandProperty Content }for i in {1..10}; do curl -s "http://$INGRESS_IP" | grep -E "Hello|Version|Hostname" || true done