Traffic Mirroring and Service Virtualization
Deploy Preference v2
We’ll use version 2 of preferences service. The only difference between v1 and V2 is that v2 prints its name in capital letters (PREFERENCE).
kubectl apply -f manifests/kubernetes/preference-v2.yml
You should have 2 pods for preference based on the steps above
kubectl get pods
NAME READY STATUS RESTARTS AGE
customer-755bbbdd44-t2vjq 2/2 Running 1 6d
preference-v1-7c8b57fc49-kcsvc 2/2 Running 0 6d
preference-v2-f74bcc999-lwlbf 2/2 Running 0 36s
recommendation-v1-798bf87d96-stzqt 2/2 Running 7 6d
Send several requests to the customer endpoint
while true; do curl $customer; sleep .5; done
In a new terminal, check the logs of recommendation-v2
kubectl logs -f `kubectl get pods|grep preference-v2|awk '{ print $1 }'` -c preference
The default Kubernetes behavior is to round-robin load-balance across all available pods behind a single Service.
So after running several times you’ll get some combinations of:
customer => preference => recommendation v1 from '798bf87d96-stzqt': 176 customer => PREFERENCE => recommendation v1 from '798bf87d96-stzqt': 177 customer => preference => recommendation v1 from '798bf87d96-stzqt': 178 customer => PREFERENCE => recommendation v1 from '798bf87d96-stzqt': 179
and see what happens when you run
kubectl apply -f manifests/istio/traffic-mirroring/preference-destination-rule-v1-v2.yml
kubectl apply -f manifests/istio/traffic-mirroring/preference-v1-mirror-v2-virtual-service.yml
curl $customer
The customer has stopped calling preference:v2
customer => preference => recommendation v1 from '798bf87d96-stzqt': 196
customer => preference => recommendation v1 from '798bf87d96-stzqt': 198
customer => preference => recommendation v1 from '798bf87d96-stzqt': 200
...
But preference:v2 still receiving requests:
preference v2 request from pod: f74bcc999-lwlbf
preference v2 request from pod: f74bcc999-lwlbf
preference v2 request from pod: f74bcc999-lwlbf
Clean up
kubectl delete -f manifests/istio/traffic-mirroring/preference-destination-rule-v1-v2.yml
kubectl delete -f manifests/istio/traffic-mirroring/preference-v1-mirror-v2-virtual-service.yml
Virtualizing Mirrored Service Dependencies
To avoid side-effects from the version 2 of preferences service, instead of communicating with recommendation service, we are going to make the preference:v2 communicate with a virtualized recommendation service.
Service virtualization can be understood as something similar as mocking where instead of mocking components (classes), you are mocking remote services.
For this concrete case, virtualized recommendation service will return recommendation v2 from 'virtualized': 2
.
kubectl apply -f manifests/kubernetes/recommendation-virtualized.yml
Mirroring Traffic to Preference
After this step, you should have three versions of recommendation service (v1, v2 and virtualized).
NAME READY STATUS RESTARTS AGE customer-755bbbdd44-t2vjq 2/2 Running 1 6d preference-v1-7c8b57fc49-kcsvc 2/2 Running 0 3h preference-v2-f74bcc999-lwlbf 2/2 Running 4 35m recommendation-v1-798bf87d96-stzqt 2/2 Running 7 3h recommendation-virtualized-5f9678d7d8-6lhx4 2/2 Running 0 30s
Send several requests to see their responses
while true; do curl $customer; sleep .5; done
The default Kubernetes behavior is to round-robin load-balance across all available pods behind a single Service.
So after running several times you’ll get some combinations of:
customer => PREFERENCE => recommendation v1 from '798bf87d96-stzqt': 233 customer => preference => recommendation v2 from 'virtualized': 2 customer => PREFERENCE => recommendation v2 from 'virtualized': 2 customer => preference => recommendation v1 from '798bf87d96-stzqt': 234 customer => PREFERENCE => recommendation v1 from '798bf87d96-stzqt': 235 customer => preference => recommendation v2 from 'virtualized': 2 customer => PREFERENCE => recommendation v2 from 'virtualized': 2
Notice that now the v2
reaches all recommendation services.
Let’s avoid this by just sending traffic that comes from preference v2 service to the virtualized recommendation service.
kubectl apply -f manifests/istio/routing-simple/recommendation-destination-rule-v1.yml
kubectl apply -f manifests/istio/service-virtualization/recommendation-virtualized-virtual-service.yml
Then do again some requests and you’ll get something like:
customer => preference => recommendation v1 from '2409176097-kcjsr': 5 customer => PREFERENCE => recommendation v1 from 'virtualized': 2 customer => preference => recommendation v2 from '1275713543-2bs5k': 6 customer => PREFERENCE => recommendation v2 from 'virtualized': 2
We’re almost done. We will again make preference:v2 a mirror for v1.
kubectl apply -f manifests/istio/traffic-mirroring/preference-v1-mirror-v2-virtual-service.yml
Read the output of the curl command and the log of preference:v2, what do you observe ?
Now all requests that are from preference v2 are redirected to virtualized recommendation service. In this way when you deploy a new service, you can mirror the traffic without worrying about side-effects on other services, since the requests are redirected to a virtualized instance instead of a production one.