Kubernetes blue/green deployment
However, there are many legacy applications out there that don't work well with rolling updates. Some applications simply need to deploy a new version and cut over to it right away. For this, we need to perform a blue/green deployment. With blue/green deployments a new copy of the application (green) is deployed alongside the existing version (blue). Then the ingress/router to the app is updated to switch to the new version (green). You then need to wait for the old (blue) version to finish the requests sent to it, but for the most part traffic to the app changes to the new version all at once.
The Blue Deployment
A Kubernetes deployment specifies a group of instances of an application. Behind the scenes, it creates a replica set which is responsible for keeping the specified number of instances up and running.
We can create our "blue" deployment by saving the following yaml to a file blue.yaml
# cat blue.yaml
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
name: nginx-1.10
spec:
replicas: 2
template:
metadata:
labels:
name: nginx
version: "1.10"
spec:
containers:
- name: nginx
image: nginx:1.10
ports:
- name: http
containerPort: 80
Create the deployment using the kubectl command
deployment "nginx-1.10" created
In In this case we have two labels, name=nginx and version=1.10. We will set these as the label selector for the service below. Save this to service.yaml.
# catservice.yaml
apiVersion: v1
kind: Service
metadata:
name: nginx
labels:
run: nginx
spec:
type: NodePort
ports:
- port: 8080
targetPort: 80
protocol: TCP
name: http
- port: 443
protocol: TCP
name: https
selector:
run: nginx
version: "1.10"
type: LoadBalancer
Creating the service will
create a load balancer that is accessible outside the cluster.
# kubectl apply -f service.yaml
service "nginx"
created
we can test that the service is
accessible and get the version.
# EXTERNAL_IP=$(kubectl get svc nginx -o jsonpath="{.status.loadBalancer.ingress[*].ip}")
# curl -s http://$EXTERNAL_IP/version | grep nginx
# kubectl get services
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kubernetesClusterIP 10.96.0.1
my-nginxClusterIP 10.100.110.46
my-nginx-web-service NodePort 10.97.35.15
nginx NodePort 10.105.211.91
nginxservice LoadBalancer 10.105.239.232 10.9.54.100
82:31691/TCP 21h
# kubectl describe service nginx
Name: nginx
Namespace: default
Labels: run=nginx
Annotations: kubectl.kubernetes.io/last-applied-configuration
{"apiVersion":"v1","kind":"Service","metadata":{"annotations":{},"labels":{"run":"nginx"},"name":"nginx","namespace":"default"},"spec":{"p...
Selector: run=nginx
Type: NodePort
IP: 10.105.211.91
Port: http 8080/TCP
TargetPort: 80/TCP
NodePort: http 32715/TCP
Endpoints:
Port: https 443/TCP
TargetPort: 443/TCP
NodePort: https 32580/TCP
Endpoints:
Session Affinity: None
External Traffic Policy: Cluster
Events:
# curl -s http://10.105.125.248:80
<title>Welcome to nginx!</title>
<style>
body {
width: 35em;
margin: 0 auto;
font-family: Tahoma, Verdana, Arial, sans-serif;
}
</style>
Welcome to nginx!
If you see this page, the nginx web server is successfully installed and
working. Further configuration is required.
Thank you for using Nginx.
Now we are ready to deploy a new version.
Update the application :
A new Deployment will be created to update the application and the Service will be updated to point at the new version.
Create the Green Deployment
The Green Deployment is
created by updating to the next version. An entirely new Deployment will be
created with different labels. Note that these labels don't match the Service
yet and so requests will not be sent to pods in the Deployment
# cat green.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-1.11
spec:
selector:
matchLabels:
run: nginx-1.11
replicas: 2
template:
metadata:
labels:
run: nginx-1.11
spec:
containers:
- name: nginx
image: nginx:1.11
ports:
- name: http
containerPort: 80
create the new deployment
# kubectl apply -f green.yaml
deployment "nginx-1.11" created
Now we have two deployments but the service is still pointing to the "blue" one.
To cut over to the "green" deployment, we will update the selector for the service. Edit the service.yaml and change the selector version to "1.11". That will make it so that it matches the pods on the "green" deployment.
# cat service.yaml
apiVersion: v1
kind: Service
metadata:
name: nginx
labels:
run: nginx
spec:
type: NodePort
ports:
- port: 8080
targetPort: 80
protocol: TCP
name: http
- port: 443
protocol: TCP
name: https
selector:
run: nginx
version: "1.11"
type: LoadBalancer
This apply will update the existing Nginx service in place.
# kubectl apply -f service.yaml
service "nginx" configured
Updating the selector for the
service is applied immediately and so you should see that the new version of
nginx is serving traffic
# EXTERNAL_IP=$(kubectl get svc nginx -o jsonpath="{.status.loadBalancer.ingress[*].ip}")
# curl -s http://$EXTERNAL_IP/version | grep nginx
Output json format
# curl -s http://10.105.125.248
<title>Welcome to nginx!</title>
<style>
body {
width: 35em;
margin: 0 auto;
font-family: Tahoma, Verdana, Arial, sans-serif;
}
</style>
Welcome to nginx!
If you see this page, the Nginx web server is successfully installed and
working. Further configuration is required.
For online documentation and support please refer to
Commercial support is available at
Thank you for using nginx.
To check how many pods are running
# kubectl get pods
NAME READY STATUS RESTARTS AGE
nginx-1.10-57f589cd6-27cdn 1/1 Running 0 2h
nginx-1.10-57f589cd6-lkbwr 1/1 Running 0 2h
nginx-1.11-68d55ccbfd-bcgkm 1/1 Running 0 1h
nginx-1.11-68d55ccbfd-h6hst 1/1 Running 0 1h
nginx-1.11-68d55ccbfd-pl67f 1/1 Running 0 1h
services
# kubectl get service
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kubernetesClusterIP 10.96.0.1
my-nginxClusterIP 10.100.110.46
my-nginx-web-service NodePort 10.97.35.15
nginx NodePort 10.105.211.91
nginxservice LoadBalancer 10.105.239.232 10.9.54.100 82:31691/TCP 23h
Clean up the deployment
# kubectl get deployment
NAME READY UP-TO-DATE AVAILABLE AGE
my-nginx 0/2 2 0 19h
my-nginx-web-service1 0/2 2 0 23h
nginx-1.10 0/2 2 0 18h
nginx-1.11 0/2 2 0 8m38s
# kubectl delete deployment nginx-1.10
deployment "nginx-1.10" deleted
# kubectl delete deployment nginx-1.11
deployment "nginx-1.11" deleted
# kubectl get deployment
No resources found.
# kubectl get pods
No resources found.
# kubectl get service
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kubernetesClusterIP 10.96.0.1
nginxLoadBalancer 10.105.125.248
# kubectl delete service nginx
service "nginx" deleted
# kubectl get service
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kubernetesClusterIP 10.96.0.1
Relevant Blogs:
Recent Comments
No comments
Leave a Comment
We will be happy to hear what you think about this post