Istio comes with a hand full of features aiming to solve the modern technical problems arising from the shift of monolith application to distributed microservice architecture, In this blog entry we are going to explore Traffic Management, one of the core features of a service mesh. For a better understanding a basic knowledge about Istio is required for that you can check this Introduction.
Catchup
Once Istio is configured, It becomes the control plane of the application network, allowing to manage service traffic without remodeling the services themselves. This unleashes new capabilities, especially in regards to deployment strategy such as the Canary and Blue/Green deployments, but also the Circuit Breaker pattern and more.. Those capabilities relies on a couple of Istio custom resources like Virtual Service and Destination Rule, So let’s check out how they look like in action
As we can see in the diagram the service, kubernetes resource, load balance the traffic between all the pods with the label configured in the Selector property. This highlights how different versions are running side by side which is problematic, Luckely the Istio approach with DestinationRules and Subsets offer a fine grained traffic control. The Virtual Service in this case is aware of all the pods bound to the kubernetes service, however the DestinationRule limit the traffic to a certain subset based on labels.
#-----------/*Virtual Service*/----------
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: my-virtualservice
spec:
hosts:
- my-host
http:
- route:
- destination: #Routing all traffic coming to my-host to the v2 subset
host: my-host
subset: v2 #Defined in the Destination Rule
#-----------/*Destination Rule*/----------
apiVersion: networking.istio.io/v1alpha3
kind: DestinationRule
metadata:
name: my-destinationrule
spec:
host: my-host
subsets: # A subset is a selection of the pods based on labels.
- name: v1
labels:
version: v1
- name: v2
labels:
version: v2
Dark launch
The concept is to launch a version of the application that’s only accessible to the test team or specific users, It’s a great way to gain confidence in new features. Admitting that we have the same DestinationRule created we need to fine tune the Virtual Service to achieve this kind of behaviour.
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: reviews
spec:
hosts:
- reviews
http:
- match:
- headers:
end-user: # header key
exact: tester
route: # Route if pattern matches
- destination:
host: reviews
subset: v2
- route: # Else
- destination:
host: reviews
subset: v1
The previous example uses an http header with a user name as matching pattern which is not a production level scenario, normally we would have cookies or JWT tokens which we will get into in a later stage of the series. But for now, something that I found really handy in my last projects is fault injection to test the behaviour of my services when I get a specific HTTP status code. To configure this with Istio it’s a simple as adding the fault condition to the Virtual Service.
# same as before
http:
- match:
- headers:
end-user:
exact: tester
fault:
abort:
percent: 50 # Only 50% of the request will fault
httpStatus: 503
# same as before
Blue/Green Deployment
After gaining confidence in the new features by making sure they work as expected and that the system is resilient enough through dark launches, It’s time to release it to big public and this is a typical scenario where you want to have a sort of a backup plan in case of things go wrong. That’s where Blue/Green deployment comes into play by offering a smooth transition between versions and allowing easy rollbacks.
A pre-requirement to understand how perform such a release on the network level only, we need to get familiar with the concept of Gateway in Istio. It’s a custom resource that
describes a load balancer operating at the edge of the mesh receiving incoming or outgoing HTTP/TCP connections.
That’s the offcial definition , but let me try to break that down for you with the following diagram
The takeway is that when users are trying to reach test.myapp.com the gateway is going to redirect the traffic to the virtual service with the same host name. Actually the subsets bound to virtual services are the driver of Blue/Green deployment capability as just switching it the traffic will be routed to a different version/set of pod.
apiVersion: networking.istio.io/v1alpha3
kind: Gateway
metadata:
name: my-gateway
spec:
servers:
hosts:
- "*"
- Port:
number: 80
name: http
protocol: Http
---
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: myapp
spec:
hosts:
- myapp
gateways:
- my-gateway
http:
- route:
- destination:
host: myapp
subset: v2
port:
number: 9080
---
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: myapp-test
spec:
hosts:
- test.myapp
gateways:
- my-gateway
http:
- route:
- destination:
host: myapp
subset: v1
port:
number: 9080
Canary Deployment
Very similar to the Blue/Green deployment, but instead of being radical and switching a 100% of the traffic from version 1 to version 2, This time we are going to make use of the Weight property to dose the traffic going to the new release.
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: myapp
spec:
hosts:
- myapp
gateways:
- my-gateway
http:
- route:
- destination:
host: myapp
subset: v1
port:
number: 9080
weight: 25
- destination:
host: myapp
subset: v2
port:
number: 9080
weight: 75
Circuit Breaker
This pattern is widely used in a distributed architecture aiming to handle fault scenario that might self heals in a certain amount of time and this of course increase the stability and resiliency of the system. One of the great power of Istio, It allows us to implement this pattern only by handling the network level by adding a Traffic Policy to the Destination Rule.
apiVersion: networking.istio.io/v1alpha3
kind: DestinationRule
metadata:
name: myapp
spec:
host: myapp
trafficPolicy:
tls:
mode: ISTIO_MUTUAL
subsets:
- name: v1
labels:
version: v1
- name: v2
labels:
version: v2
trafficPolicy:
outlierDetection:
consecutiveErrors: 2 # If 2 errors in a 1min interval then eject for 5min
interval: 1m
baseEjectionTime: 5m
maxEjectionPercent: 100 # The percentage of the endpoints that the policy can eject
Wrapup
We’ve seen what a powerful set of capabilities offered by the custom resources that Istio brings up, allowing a fine grain service traffic management. In the next blog entry Security is going to be in the spotlight, we will check out mTLS and Istio policies, Also some practical examples of how to secure access to services using the AuthorizationPolicy resource.