We are going to deploy an nginx app with 2 versions, blue and green. We will mount the index.html to the deployments to show which version we are looking at. Then we will create a service with labels pointing to both versions, and control the flow of traffic between the blue version to the green version through pod replicas in the deployment.
Create the demo namespace
k create ns demo
k config set-context $(k config current-context) --namespace=demo
Create a pod that we will use to curl the service.
k run curler --image=nginx --port=80 --restart=Never --command -- sleep 9999
Create a blue deployment and mount index.html from a configmap
kubectl apply -f -<<EOF
apiVersion: apps/v1
kind: Deployment
metadata:
labels:
app: nginx
version: blue
name: nginx-blue
spec:
replicas: 4
selector:
matchLabels:
app: nginx
strategy: {}
template:
metadata:
labels:
app: nginx
version: blue
spec:
containers:
- image: nginx
name: nginx
ports:
- containerPort: 80
volumeMounts:
- mountPath: /usr/share/nginx/html
name: index
volumes:
- name: index
configMap:
name: blue-config
---
apiVersion: v1
data:
index.html: |
<html>
<body>
Blue Version
</body>
</html>
kind: ConfigMap
metadata:
name: blue-config
namespace: demo
EOF
Create a green deployment and mount index.html from a configmap
kubectl apply -f -<<EOF
apiVersion: apps/v1
kind: Deployment
metadata:
labels:
app: nginx
version: green
name: nginx-green
spec:
replicas: 1
selector:
matchLabels:
app: nginx
strategy: {}
template:
metadata:
labels:
app: nginx
version: green
spec:
containers:
- image: nginx
name: nginx
ports:
- containerPort: 80
volumeMounts:
- mountPath: /usr/share/nginx/html
name: index
volumes:
- name: index
configMap:
name: green-config
---
apiVersion: v1
data:
index.html: |
<html>
<body>
Green Version
</body>
</html>
kind: ConfigMap
metadata:
name: green-config
namespace: demo
EOF
Create a service with the label selector pointing to both versions and control the canary rollout based on replicas
kubectl apply -f -<<EOF
apiVersion: v1
kind: Service
metadata:
labels:
app: nginx
name: nginx
namespace: demo
spec:
ports:
- port: 80
protocol: TCP
targetPort: 80
selector:
app: nginx
sessionAffinity: None
type: ClusterIP
EOF
We should have 75% of the traffic going to the blue version right now and 25% going to green.
Now lets curl the nginx service. (Make sure you copy the command as it, no \)
for x in $(seq 4); do k exec -it pod/curler -- curl http://nginx:80; done
expected output
<html>
<body>
Blue Version
</body>
</html>
<html>
<body>
Blue Version
</body>
</html>
<html>
<body>
Blue Version
</body>
</html>
<html>
<body>
Green Version
</body>
</html>
Lets split the traffic 50/50.
k patch deploy/nginx-green -p '{"spec":{"replicas":4}}'
The blue and green deployment both have 4 replicas, so the traffic should be distrubted evenly mongst the pods.
Now lets curl the nginx service again. (Make sure you copy the command as it, no \)
for x in $(seq 4); do k exec -it pod/curler -- curl http://nginx:80; done
expected output
<html>
<body>
Blue Version
</body>
</html>
<html>
<body>
Green Version
</body>
</html>
<html>
<body>
Green Version
</body>
</html>
<html>
<body>
Blue Version
</body>
</html>
You have successfully done a blue/green deployment
Lets split the traffic 25/75.
k patch deploy/nginx-green -p '{"spec":{"replicas":16}}'
The blue deployment has 4 replicas, the green has 16. 75% of Traffic should go to green.
for x in $(seq 4); do k exec -it pod/curler -- curl http://nginx:80; done
output:
<html>
<body>
Green Version
</body>
</html>
<html>
<body>
Green Version
</body>
</html>
<html>
<body>
Green Version
</body>
</html>
<html>
<body>
Blue Version
</body>
</html>
k delete pods,svc,deploy,cm --all --wait
k delete ns demo --wait