Using Traffic Shifting on Istio to make Blue/Green Deployments on Kubernetes
Blue/green deployments let you roll out a new version while keeping the old one ready, and Istio makes shifting traffic between the two almost trivial. In this post we’ll do exactly that on Kubernetes.
Once Istio is installed, the first thing to set up is a namespace with sidecar injection enabled. I’m relying on a namespace label so the injection happens automatically:
kubectl create ns webischia && kubectl label namespace webischia istio-injection=enabled
Our test YAML:
apiVersion: v1
kind: Service
metadata:
name: webischia
labels:
app: webischia
spec:
ports:
- port: 80
name: http
selector:
app: webischia
---
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
name: webischia-v1
spec:
replicas: 1
template:
metadata:
labels:
app: webischia
version: v1
spec:
containers:
- name: webischia
image: ffahri/bluedep
imagePullPolicy: IfNotPresent
ports:
- containerPort: 80
---
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
name: webischia-v2
spec:
replicas: 1
template:
metadata:
labels:
app: webischia
version: v2
spec:
containers:
- name: webischia
image: ffahri/greendep
imagePullPolicy: IfNotPresent
ports:
- containerPort: 80
---
Apply this YAML using:
kubectl apply -f webischia.yaml -n webischia
root@frankfurt-kubeadm1-ub2g:~/# kubectl apply -f blue-green.yaml -n webischia
service/webischia created
deployment.extensions/webischia-v1 created
deployment.extensions/webischia-v2 created
With the two versions running, the next piece is an Istio gateway for our service along with the route rules that decide where traffic goes.
apiVersion: networking.istio.io/v1alpha3
kind: DestinationRule
metadata:
name: webischia
spec:
host: webischia
subsets:
- name: v1
labels:
version: v1
- name: v2
labels:
version: v2
apiVersion: networking.istio.io/v1alpha3
kind: Gateway
metadata:
name: webischia-gateway
spec:
selector:
istio: ingressgateway # use istio default controller
servers:
- port:
number: 80
name: http
protocol: HTTP
hosts:
- "*"
---
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: webischia
spec:
hosts:
- "*"
gateways:
- webischia-gateway
http:
- match:
- uri:
exact: /
route:
- destination:
host: webischia
subset: v1
port:
number: 80
kubectl apply -f gateway.yaml -n webischia
gateway.networking.istio.io/webischia-gateway created
virtualservice.networking.istio.io/webischia created
These create the gateway and virtual service for our app.
With routing in place, we can reach the system through istio-ingressgateway and test it.
Since we pointed all traffic at v1, every response should be the blue WebIschia.
for i in {0..999} ; do curl http://159.89.3**.***/;echo ; done
<h1 style='color:blue'>Blue WebIschia</h1>
<h1 style='color:blue'>Blue WebIschia</h1>
<h1 style='color:blue'>Blue WebIschia</h1>
<h1 style='color:blue'>Blue WebIschia</h1>
<h1 style='color:blue'>Blue WebIschia</h1>
Monitoring of these services (thanks to Istio for taking care of it all 🙂):
Now suppose we’ve built a new version and want to ease it in, splitting traffic 80% to 20%.
- route:
- destination:
host: webischia
subset: v1
weight: 80
- destination:
host: webischia
subset: v2
weight: 20
As you can see, the graph confirms that the traffic shifting has taken effect.
Best of all, this happens without any server-side or client-side errors.
From here we can push further and set the weights to 80% green and 20% blue.
- route:
- destination:
host: webischia
subset: v1
weight: 20
- destination:
host: webischia
subset: v2
weight: 80
And finally, once we’re confident, we can shift all the way to green.
- route:
- destination:
host: webischia
subset: v1
weight: 0
- destination:
host: webischia
subset: v2
weight: 100
Conclusion:
Istio shows us just how easily traffic shifting can be done. On top of that, observability is a big deal, and it comes almost for free with Istio.




