In this 3 post we
will see how to do a blue/green deployment. A blue/green deployment is
different from the rolling update in which a green version of the application
is deployed along with the blue version. After testing the green version and
once satisfied we will update the service to point to the green version. This
way we will route the traffic from blue version to green version. This is done
by playing with the labels in the selector fields. Once the traffic is moved to
the green version, the blue version pods are terminated.
Lets create the blue deployment first as,
[root@manja17-I13330 kubenetes-config]# cat blue-deployment.yml
apiVersion: v1
kind: Service
metadata:
name: testing-service
labels:
app: testing-service
spec:
type: NodePort
ports:
- name: http
port: 80
targetPort: http
# Note here that we match both the app and the version
selector:
app: testing-service
version: "1.0"
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: testing-service-v1
labels:
app: testing-service
spec:
replicas: 3
selector:
matchLabels:
app: testing-service
version: "1.0"
template:
metadata:
labels:
app: testing-service
version: "1.0"
spec:
containers:
- name: testing-service
image: docker.io/jagadesh1982/testing-service
ports:
- name: http
containerPort: 9876
env:
- name: VERSION
value: "1.0"
[root@manja17-I13330
kubenetes-config]# kubectl apply -f blue-deployment.yml
service
"testing-service" created
deployment.apps
"testing-service-v1" created
[root@manja17-I13330
kubenetes-config]# kubectl get pods
NAME READY STATUS
RESTARTS AGE
testing-service-v1-bc6866889-g8zrr 1/1 Running 0 5m
testing-service-v1-bc6866889-lj8f7 1/1 Running 0 5m
testing-service-v1-bc6866889-qnr2r 1/1 Running 0 5m
[root@manja17-I13330
kubenetes-config]# kubectl get svc
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 1d
testing-service NodePort
10.110.200.110 <none> 80:30009/TCP 5m
[root@manja17-I13330
kubenetes-config]# curl 10.99.143.66/info
{"host":
"10.99.143.66", "version": "1.0",
"from": "10.32.0.1"}
Lets run the green
deployment,with the below manifest file,
[root@manja17-I13330 kubenetes-config]# cat green-deployment.yml
apiVersion: apps/v1
kind: Deployment
metadata:
name: testing-service-v2
labels:
app: testing-service
spec:
replicas: 3
selector:
matchLabels:
app: testing-service
version: "2.0"
template:
metadata:
labels:
app: testing-service
version: "2.0"
spec:
containers:
- name: testing-service
image: docker.io/jagadesh1982/testing-service
ports:
- name: http
containerPort: 9876
env:
- name: VERSION
value: "2.0"
[root@manja17-I13330
kubenetes-config]# kubectl apply -f green-deployment.yml
deployment.apps
"testing-service-v2" created
[root@manja17-I13330
kubenetes-config]# kubectl get pods
NAME READY
STATUS RESTARTS AGE
testing-service-v1-bc6866889-g8zrr 1/1 Running
0 8m
testing-service-v1-bc6866889-lj8f7 1/1 Running
0 8m
testing-service-v1-bc6866889-qnr2r 1/1 Running
0 8m
testing-service-v2-7f966d5d4c-mb2fk 1/1
Running 0 2m
testing-service-v2-7f966d5d4c-qs6fz 1/1
Running 0 2m
testing-service-v2-7f966d5d4c-z4tj4 1/1
Running 0 2m
Side by side, 3 pods are running with version 2
but the service still send traffic to the first deployment. If necessary, you can manually test one of the pod by
port-forwarding it to your local environment. Once your are ready, you can switch the traffic to the new
version by patching the service to send traffic to all pods with label
version=v2.0.0:
[root@manja17-I13330
kubenetes-config]# kubectl patch service testing-service -p
'{"spec":{"selector":{"version":"2.0"}}}'
service
"testing-service" patched
[root@manja17-I13330
kubenetes-config]# kubectl get svc
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 1d
testing-service NodePort
10.99.143.66 <none> 80:30126/TCP 3m
[root@manja17-I13330
kubenetes-config]# curl 10.99.143.66/info
{"host":
"10.99.143.66", "version": "2.0",
"from": "10.32.0.1"}
If you want to
rollback to the older version , we can use
[root@manja17-I13330
kubenetes-config]# kubectl patch service testing-service -p
'{"spec":{"selector":{"version":"1.0"}}}'
service "testing-service"
patched
[root@manja17-I13330
kubenetes-config]# kubectl get svc
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 1d
testing-service NodePort 10.99.143.66 <none> 80:30126/TCP 4m
[root@manja17-I13330
kubenetes-config]# curl 10.99.143.66/info
{"host":
"10.99.143.66", "version": "1.0",
"from": "10.32.0.1"}
[root@manja17-I13330
kubenetes-config]# kubectl get deploy
NAME DESIRED
CURRENT UP-TO-DATE AVAILABLE
AGE
testing-service-v1 3 3 3 3 5m
testing-service-v2 3 3 3 3 2m
Once we are happy with the green version, delete the blue deployment using,
[root@manja17-I13330
kubenetes-config]# kubectl delete deploy testing-service-v1
deployment.extensions
"testing-service-v1" deleted
Now check the pods ,
[root@manja17-I13330
kubenetes-config]# kubectl get pods
NAME READY STATUS RESTARTS AGE
testing-service-v1-bc6866889-dthrt 1/1 Terminating 0 5m
testing-service-v1-bc6866889-nk282 1/1 Terminating 0 5m
testing-service-v1-bc6866889-rxdtz 1/1 Terminating 0 5m
testing-service-v2-76dcdbd6bc-g56bh 1/1 Running 0 3m
testing-service-v2-76dcdbd6bc-jbvkw 1/1 Running 0 3m
testing-service-v2-76dcdbd6bc-s4zg2 1/1 Running 0 3m
We can see the blue version of pods are being terminated and green version are up and running. This is how we will be doing a blue/green deployment in kubernetes.
More to Come, Happy learning :-)
No comments :
Post a Comment