Blue Green Deployment
Blue Green Deployment
Kubernetes doesn't have (as of now)
strategy: BlueGreen
like we hadRollingUpdate
andRecreate
.
How blue-green deployment strategy works?
- If we want to upgrade the instances of V1 (Blue), we create exactly the same number of instances of V2 (Green) alongside V1 (Blue).
- Initially Service that we are using to expose our app will be pointing to V1 (Blue).
- After testing that the V2 (Green) meets all the requirements the traffic is switched from V1 (Blue) to V2 (Green).
- This technique reduces downtime by running two version of app at the same time.
- But only one version of app is live to user.
- For our example, Blue is currently live, and Green is idle.
- But after upgrade Green will be live, and Blue will be idle. (Later on Blue will be deleted)
Advantages
- With this strategy we can have instant roll back, as we still have old version of app running in background.
- Unlike Rolling Update we don't run two version of app once.
Disadvantages
- Blue Green deployment strategy might be expensive. When updating the app we use double resource.
Blue Green Stages
Initial State
+-------------+
| |
+-------+ Service |
| | |
| +-------------+
|
|
|BLUE| v
+---------------------------+
| +-------------------+ |
| |Pod_1||Pod_1||Pod_1| |
| --------------------+ |
| -------------+ +-------+ |
| |Deployment_1| |Replica| |
| -------------+ | Set_1 | |
| +-------+ |
+---------------------------+
- Initially we will have V1 app running, for now let's say Blue.
Rollout Update
+--------------+
| |
+-------+ Service |
| | |
| +--------------+
|
|
|BLUE| v |GREEN|
+---------------------------+ +---------------------------+
| +-------------------+ | | +-------------------+ |
| |Pod_1||Pod_1||Pod_1| | | |Pod_2||Pod_2||Pod_2| |
| --------------------+ | | --------------------+ |
| | | |
| | | |
| -------------+ +-------+ | | -------------+ +-------+ |
| |Deployment_1| |Replica| | | |Deployment_2| |Replica| |
| -------------+ | Set_1 | | | -------------+ | Set_2 | |
| +-------+ | | +-------+ |
+---------------------------+ +---------------------------+
- When rollout starts we create our V2 (Green), ideally we will create same number of Pods replicas.
- Notice, we are creating totally new
Deployment
here.
Switch to new version
+--------------+
| |
| Service +------+
| | |
+--------------+ |
|
|
|BLUE| |GREEN| v
+---------------------------+ +---------------------------+
| +-------------------+ | | +-------------------+ |
| |Pod_1||Pod_1||Pod_1| | | |Pod_2||Pod_2||Pod_2| |
| --------------------+ | | --------------------+ |
| | | |
| | | |
| -------------+ +-------+ | | -------------+ +-------+ |
| |Deployment_1| |Replica| | | |Deployment_2| |Replica| |
| -------------+ | Set_1 | | | -------------+ | Set_2 | |
| +-------+ | | +-------+ |
+---------------------------+ +---------------------------+
- To make our new version of app V2 Green live, we will have to point
Service
to newly created Pod. - For Kubernetes
Service
we just change the label selector.
Clean up or roll back
- At this stage, we can either cleanup resources or we can roll back to our previous version.
- If we think new version of app is stable, we can delete the old Pods / Deployments
- But if we need to do a roll back, it is very easy. Just change the Service label selector again.
Blue Green Deployment With Kubernetes
Deploy the V1 App
- Create a
Deployment
with following configuration
apiVersion: apps/v1
kind: Deployment
metadata:
name: web-v1
labels:
version: v1
env: prod
spec:
replicas: 3
selector:
matchLabels:
env: prod
version: v1
template:
metadata:
name: web-v1
labels:
version: v1
env: prod
spec:
containers:
- image: amantuladhar/docker-kubernetes:v1-web
name: web-v1
#probes
- Notice how I am appending
-v1
to Deployment, ReplicaSet and Pods name. This is important because we don't want to replace the existingDeployment
resource.
Create a Service
apiVersion: v1
kind: Service
metadata:
name: web
spec:
type: NodePort
ports:
- port: 80
targetPort: 8080
nodePort: 30000
selector:
env: prod
version: v1
- Service at the moment is selecting Pods with
version: v1
label.
Update to V2 App
apiVersion: apps/v1
kind: Deployment
metadata:
name: web-v2
labels:
version: v2
env: prod
spec:
replicas: 3
selector:
matchLabels:
env: prod
version: v2
template:
metadata:
name: web-v2
labels:
version: v2
env: prod
spec:
containers:
- image: amantuladhar/docker-kubernetes:v2-web
name: web-v2
#probes
- We create a new
Deployment
*-v2. - ReplicaSet / Pods labels are also suffixed with -v2
- At the moment the Pods created by our new Deployment is not live. Service is still pointing to old version of the app.
- After all the new version Pods are ready, we can switch the Service selector.
Change the Service
selector
- You can change the Service selector using multiple technique.
- I will use
kubectl patch
kubectl patch service web --patch '{"spec": {"selector": {"version": "v2"}}}'
- After this you will see all the traffic are now redirected to new version.
Cleanup / Rollback Update
- If you want to cleanup you can delete the old
Deployment
- If you want to Rollback the update, you can use above command and change selector to
v1
kubectl patch service web --patch '{"spec": {"selector": {"version": "v1"}}}'