This is a kind of documentation or walks thought of my work, which can be called a DevSecOps diary.

Blue-Green Deployment With Vanilla K8s and Helm.

In a previous post, I have already created a k8s cluster and also deploy a simple application in k8s with helm chart.

In this post, I do explain how to refactor the helm chart a bit and make a simple blue-green deployment with that.

Check out the code to brach “helm-chart” and creak a new brach “helm-chart-blue-green” from that.

git clone https://github.com/nahidupa/k8s-eks-with-terraform.git
git checkout -b helm-chart-blue-green

At this moment each helm chart has it’s all component, it has also deployed its own service. But, as Here I want to demonstrate blue-green deployment both deployments can be the point from a single service, There is no need to install service with both helm chart.

The idea is to move the service deployment a separate helm chart, Do it first.

cd   k8s-eks-with-terraform/charts/blue-green
mkdir service
cd service
helm create blue-green-service

Remove “deployment.yaml” and “hpa.yaml” from charts.

Modify the _helpers.tpl “Selector labels” sections

before

{{/*
Selector labels
*/}}
{{- define "blue-green-service.selectorLabels" -}}
app.kubernetes.io/name: {{ include "blue-green-service.name" . }}
app.kubernetes.io/instance: {{ .Release.Name }}
{{- end }}

after

{{/*
Selector labels
*/}}
{{- define "blue-green-service.selectorLabels" -}}

app.kubernetes.io/name: {{ .Values.routeinstance }}
{{- end }}

Let’s introduce a new property “routeinstance” that will be feed from values.yaml, What it does is set the selector logic for the service, for example, if we set this to  app.kubernetes.io/name: blue-web-echo service will send traffic to blue-web-echo pods and if we set this to app.kubernetes.io/name: green-web-echo traffic will send this to green-web-echo pods.

values.yaml

routeinstance : blue-web-echo

Just put repository: nullimage and set targetPort in values.yaml file. We can clean up a lot’s here but for simplicity, I will leave that for now. 

image:
  repository: nullimage
  pullPolicy: IfNotPresent
service:
  type: LoadBalancer
  port: 8600
  targetPort: 5678

blue-green-service chart

Clean up the previously deployed helm chart from k8s.

../helm-deploy-blue-web-echo
terragrunt destroy
../helm-deploy-green-web-echo
terragrunt destroy

Now, deploy the service.

cd ../helm-deploy-blue-green-service
terragrunt apply
~ kubectl get svc -w
NAME                 TYPE           CLUSTER-IP      EXTERNAL-IP                                                                   PORT(S)          AGE
blue-green-service   LoadBalancer   10.100.131.75   a7a08e35d363b4d36bc1e674c1006c9d-696173711.ap-southeast-1.elb.amazonaws.com   8600:31911/TCP   12h
kubectl port-forward service/blue-green-service 9000:8600 -n default

Notes: (do not use port-forward is this senario, that will directly point to a pod,https://github.com/kubernetes/kubernetes/issues/15180). Use LoadBalancer or Ingres for that. Here, going to use LoadBalancer.

At this point, we will get nothing in curl output as we do not deploy any service yet.

➜  ~ curl -kis http://<loadbalencer>:8600

Now remove the service.yaml from both helm chart(blue-web-echo,green-web-echo) and Deploy the blue-web-echo first.

../helm-deploy-blue-web-echo
terragrunt apply
➜  ~ curl -kis http://<loadbalencer>:8600
HTTP/1.1 200 OK
X-App-Name: http-echo
X-App-Version: 0.2.3
Date: Thu, 02 Jul 2020 03:29:16 GMT
Content-Length: 9
Content-Type: text/plain; charset=utf-8

blue-1.0

Let’s deploy the green-web-echo

../helm-deploy-green-web-echo
terragrunt apply

Check the pod become up and running

➜  ~ kubectl get pod
NAME                              READY   STATUS    RESTARTS   AGE
blue-web-echo-686cbf9fcc-8p6jg    1/1     Running   0          3m58s
green-web-echo-78c57dc95f-rh9tr   1/1     Running   0          25s

It’s time to switch the traffic to green. before that put a continuous curl

watch curl -kis http://<loadbalencer>:8600

HTTP/1.1 200 OK
X-App-Name: http-echo
X-App-Version: 0.2.3
Date: Thu, 02 Jul 2020 03:30:51 GMT
Content-Length: 9
Content-Type: text/plain; charset=utf-8

blue-1.0

change the “routeinstance : blue-web-echo” to “routeinstance : green-web-echo” in blue-green-service and do terragrunt apply.

cd ../helm-deploy-blue-green-service
terragrunt apply
watch curl -kis http://<loadbalencer>:8600

HTTP/1.1 200 OK
X-App-Name: http-echo
X-App-Version: 0.2.3
Date: Thu, 02 Jul 2020 03:35:31 GMT
Content-Length: 10
Content-Type: text/plain; charset=utf-8

green-1.0

Now we can see traffic is redirected to green pods.

This is just a demonstration purpose implementation, We can do this even better way with a service mesh.

Please read posts regarding istio (service mesh).