Using Traffic Shifting on Istio to make Blue/Green Deployments on Kubernetes

Sun, Oct 21, 2018 3-minute read

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.