Istio for Promoting Services (Feature Graduation)
The idea behind service promotion is that you are able to promote your different versions of a service so it can be reached gradually by your public traffic.
What you define is different levels where your service is promoted, and in each of this level, the service is meant to be more stable than in the previous one.You can think about graduating services to classes of users.
There are several ways of doing it, but one way we are using in OpenShift IO is by allowing the user to choose if he wants to try the latest deployed version of the application (experimental level) or a stable version of the application (stable level).
This means that in the public cluster you have more than one version of the same service deployed, and the public traffic is able to reach it as well.
So let’s see how to implement this approach using Istio.
We can experiment with Istio controlling traffic by making a change to RecommendationVerticle.java
like the following and creating a "v3" docker image.
private static final String RESPONSE_STRING_FORMAT = "recommendation v3 from '%s': %d\n";
There is also a second deployment.yml
file to label things correctly
oc apply -f <(istioctl kube-inject -f ) -n tutorial
oc get pods -w -n tutorial
or
kubectl apply -f <(istioctl kube-inject -f ../../kubernetes/Deployment-v3.yml) -n tutorial
kubectl get pods -w -n tutorial
mvn clean package -f recommendation/java/vertx
oc cancel-build bc/recommendation-v3 -n tutorial
oc delete svc/recommendation-v3 -n tutorial
oc start-build recommendation-v3 --from-dir=. --follow -n tutorial
Wait for those pods to show "2/2", the istio-proxy/envoy sidecar is part of that pod.
NAME READY STATUS RESTARTS AGE
customer-3600192384-fpljb 2/2 Running 0 17m
preference-243057078-8c5hz 2/2 Running 0 15m
recommendation-v1-60483540-9snd9 2/2 Running 0 12m
recommendation-v2-2815683430-vpx4p 2/2 Running 0 15s
recommendation-v3-9834632434-urd34 2/2 Running 0 15s
and test the customer endpoint until you can see that v3 has been reached.
curl customer-tutorial.$(minishift ip).nip.io
With 3 versions of service recommendation deployed, now we can define 3 different level of access.For example experimental, beta and production.
With Istio, we can use routing for sending traffic depending on users configuration.
Now, we need to set a header named user-preference
with some specific value:
- For version 3
123
(experimental)12
(beta)For version 1
- empty (production)
The reason behind using these approach is the next one.In this example, we have three levels experimental, beta and production, and we set a number to each level, 3 is the most unstable version while one is the most stable version.
So, for example, a user that sets its preferences to experimental it means that he needs to reach experimental or if no eperimental then _beta or by default production.This effectively means setting that he wants to reach all levels 123
.And the same applies to any other level defined by the user.
curl -H "user-preference: 123" customer-tutorial.$(minishift ip).nip.io
customer => preference => recommendation v3 from '6953441398-tyw25': 1
curl -H "user-preference: 12" customer-tutorial.$(minishift ip).nip.io
customer => preference => recommendation v2 from '3490080923-usw67': 2
customer => preference => recommendation v1 from '9834514598-knc40': 10
One interesting point here is that if you open you’ll see that the header is set to baggage-user-preference
meanwhile in curl
it is set to user-preference
.
The reason is that in customer service (CustomerController.java), io.opentracing.Tracer
class is used to set as baggage item the user-preference
header.In this way, the header is populated across all services without having to copy it manually in each service, since by default headers are not populated automatically.
Now let’s make a promotion of the versions, so version 1 is not reachable anymore, version 2 is the new production and version 3 is the new beta.
istioctl replace -f -n tutorial
curl -H "user-preference: 123" customer-tutorial.$(minishift ip).nip.io
customer => preference => recommendation v3 from '6953441398-tyw25': 2
curl -H "user-preference: 12" customer-tutorial.$(minishift ip).nip.io
customer => preference => recommendation v3 from '6953441398-tyw25': 3
curl customer-tutorial.$(minishift ip).nip.io
customer => preference => recommendation v2 from '3490080923-usw67': 3
So versions of a service are promoted without having to redeploy anything nor changing your code.
oc delete all -l app=recommendation,version=v3
or
kubectl delete all -l app=recommendation,version=v3
istioctl delete -f istiofiles/destination-rule-recommendation-v1-v2-v3.yml -n tutorial