Skip to content

Commit 1bdb42d

Browse files
committed
kube
1 parent 671528f commit 1bdb42d

28 files changed

Lines changed: 1273 additions & 0 deletions
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
Blue/green deployment
2+
=====================
3+
4+
> Version B is released alongside version A, then the traffic is switched to
5+
version B. Also known as red/black deployment.
6+
7+
![kubernetes blue-green deployment](grafana-blue-green.png)
8+
9+
The blue/green deployment strategy differs from a ramped deployment, version B
10+
(green) is deployed alongside version A (blue) with exactly the same amount of
11+
instances. After testing that the new version meets all the requirements the
12+
traffic is switched from version A to version B at the load balancer level.
13+
14+
**You can apply the blue/green deployment technique for a single service or
15+
multiple services using an Ingress controller:**
16+
17+
- [multiple services using Ingress](multiple-services/)
18+
- [single service](single-service/)
180 KB
Loading
Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
Blue/green deployment to release multiple services simultaneously
2+
=================================================================
3+
4+
> In this example, we release a new version of 2 services simultaneously using
5+
the blue/green deployment strategy. [Traefik](https://traefik.io) in used as
6+
Ingress controller, this example would also work with the
7+
[Nginx Ingress controller](https://github.com/kubernetes/ingress-nginx).
8+
9+
## Steps to follow
10+
11+
1. service a and b are serving traffic
12+
1. deploy new version of both services
13+
1. wait for all services to be ready
14+
1. switch incoming traffic from version 1 to version 2
15+
1. shutdown version 1
16+
17+
## In practice
18+
19+
Install the latest version of
20+
[Helm](https://docs.helm.sh/using_helm/#installing-helm), then install
21+
[Traefik](https://traefik.io/):
22+
23+
```bash
24+
# Deploy Traefik with Helm
25+
$ helm install \
26+
--name=traefik \
27+
--version=1.60.0 \
28+
--set rbac.enabled=true \
29+
stable/traefik
30+
31+
# Deploy version 1 of application a and b and the ingress
32+
$ kubectl apply -f app-a-v1.yaml -f app-b-v1.yaml -f ingress-v1.yaml
33+
34+
# Test if the deployment was successful
35+
$ ingress=$(minikube service traefik --url | head -n1)
36+
$ curl $ingress -H 'Host: a.domain.com'
37+
Host: my-app-a-v1-66fb8d6f99-hs8jr, Version: v1.0.0
38+
39+
$ curl $ingress -H 'Host: b.domain.com'
40+
Host: my-app-b-v1-5766557f99-dpghc, Version: v1.0.0
41+
42+
# To see the deployment in action, open a new terminal and run the following
43+
# command
44+
$ watch kubectl get po
45+
46+
# Then deploy version 2 of both applications
47+
$ kubectl apply -f app-a-v2.yaml -f app-b-v2.yaml
48+
49+
# Wait for both applications to be running
50+
$ kubectl rollout status deploy my-app-a-v2 -w
51+
deployment "my-app-a-v2" successfully rolled out
52+
53+
$ kubectl rollout status deploy my-app-b-v2 -w
54+
deployment "my-app-b-v2" successfully rolled out
55+
56+
# Check the status of the deployment, then when all the pods are ready, you can
57+
# update the ingress
58+
$ kubectl apply -f ingress-v2.yaml
59+
60+
# Test if the deployment was successful
61+
$ curl $ingress -H 'Host: a.domain.com'
62+
Host: my-app-a-v2-6b58d47c5f-nmzds, Version: v2.0.0
63+
64+
$ curl $ingress -H 'Host: b.domain.com'
65+
Host: my-app-b-v2-5c9dc59959-hp5kh, Version: v2.0.0
66+
67+
# In case you need to rollback to the previous version
68+
$ kubectl apply -f ingress-v1.yaml
69+
70+
# If everything is working as expected, you can then delete the v1.0.0
71+
# deployment
72+
$ kubectl delete -f ./app-a-v1.yaml -f ./app-b-v1.yaml
73+
```
74+
75+
### Cleanup
76+
77+
```bash
78+
$ kubectl delete all -l app=my-app
79+
$ helm del --purge traefik
80+
```
Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
apiVersion: v1
2+
kind: Service
3+
metadata:
4+
name: my-app-a-v1
5+
labels:
6+
app: my-app
7+
spec:
8+
ports:
9+
- name: http
10+
port: 80
11+
targetPort: http
12+
13+
# Note here that we match both the app and the version
14+
selector:
15+
app: my-app-a
16+
version: v1.0.0
17+
---
18+
apiVersion: apps/v1
19+
kind: Deployment
20+
metadata:
21+
name: my-app-a-v1
22+
labels:
23+
app: my-app
24+
spec:
25+
replicas: 2
26+
selector:
27+
matchLabels:
28+
app: my-app-a
29+
version: v1.0.0
30+
template:
31+
metadata:
32+
labels:
33+
app: my-app-a
34+
version: v1.0.0
35+
annotations:
36+
prometheus.io/scrape: "true"
37+
prometheus.io/port: "9101"
38+
spec:
39+
containers:
40+
- name: my-app-a
41+
image: containersol/k8s-deployment-strategies
42+
ports:
43+
- name: http
44+
containerPort: 8080
45+
- name: probe
46+
containerPort: 8086
47+
env:
48+
- name: VERSION
49+
value: v1.0.0
50+
livenessProbe:
51+
httpGet:
52+
path: /live
53+
port: probe
54+
initialDelaySeconds: 5
55+
periodSeconds: 5
56+
readinessProbe:
57+
httpGet:
58+
path: /ready
59+
port: probe
60+
periodSeconds: 5
Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
apiVersion: v1
2+
kind: Service
3+
metadata:
4+
name: my-app-a-v2
5+
labels:
6+
app: my-app
7+
spec:
8+
ports:
9+
- name: http
10+
port: 80
11+
targetPort: http
12+
13+
# Note here that we match both the app and the version
14+
selector:
15+
app: my-app-a
16+
version: v2.0.0
17+
---
18+
apiVersion: apps/v1
19+
kind: Deployment
20+
metadata:
21+
name: my-app-a-v2
22+
labels:
23+
app: my-app
24+
spec:
25+
replicas: 2
26+
selector:
27+
matchLabels:
28+
app: my-app-a
29+
version: v2.0.0
30+
template:
31+
metadata:
32+
labels:
33+
app: my-app-a
34+
version: v2.0.0
35+
annotations:
36+
prometheus.io/scrape: "true"
37+
prometheus.io/port: "9101"
38+
spec:
39+
containers:
40+
- name: my-app-a
41+
image: containersol/k8s-deployment-strategies
42+
ports:
43+
- name: http
44+
containerPort: 8080
45+
- name: probe
46+
containerPort: 8086
47+
env:
48+
- name: VERSION
49+
value: v2.0.0
50+
livenessProbe:
51+
httpGet:
52+
path: /live
53+
port: probe
54+
initialDelaySeconds: 5
55+
periodSeconds: 5
56+
readinessProbe:
57+
httpGet:
58+
path: /ready
59+
port: probe
60+
periodSeconds: 5
Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
apiVersion: v1
2+
kind: Service
3+
metadata:
4+
name: my-app-b-v1
5+
labels:
6+
app: my-app
7+
spec:
8+
ports:
9+
- name: http
10+
port: 80
11+
targetPort: http
12+
13+
# Note here that we match both the app and the version
14+
selector:
15+
app: my-app-b
16+
version: v1.0.0
17+
---
18+
apiVersion: apps/v1
19+
kind: Deployment
20+
metadata:
21+
name: my-app-b-v1
22+
labels:
23+
app: my-app
24+
spec:
25+
replicas: 2
26+
selector:
27+
matchLabels:
28+
app: my-app-b
29+
version: v1.0.0
30+
template:
31+
metadata:
32+
labels:
33+
app: my-app-b
34+
version: v1.0.0
35+
annotations:
36+
prometheus.io/scrape: "true"
37+
prometheus.io/port: "9101"
38+
spec:
39+
containers:
40+
- name: my-app-b
41+
image: containersol/k8s-deployment-strategies
42+
ports:
43+
- name: http
44+
containerPort: 8080
45+
- name: probe
46+
containerPort: 8086
47+
env:
48+
- name: VERSION
49+
value: v1.0.0
50+
livenessProbe:
51+
httpGet:
52+
path: /live
53+
port: probe
54+
initialDelaySeconds: 5
55+
periodSeconds: 5
56+
readinessProbe:
57+
httpGet:
58+
path: /ready
59+
port: probe
60+
periodSeconds: 5
Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
apiVersion: v1
2+
kind: Service
3+
metadata:
4+
name: my-app-b-v2
5+
labels:
6+
app: my-app
7+
spec:
8+
ports:
9+
- name: http
10+
port: 80
11+
targetPort: http
12+
13+
# Note here that we match both the app and the version
14+
selector:
15+
app: my-app-b
16+
version: v2.0.0
17+
---
18+
apiVersion: apps/v1
19+
kind: Deployment
20+
metadata:
21+
name: my-app-b-v2
22+
labels:
23+
app: my-app
24+
spec:
25+
replicas: 2
26+
selector:
27+
matchLabels:
28+
app: my-app-b
29+
version: v2.0.0
30+
template:
31+
metadata:
32+
labels:
33+
app: my-app-b
34+
version: v2.0.0
35+
annotations:
36+
prometheus.io/scrape: "true"
37+
prometheus.io/port: "9101"
38+
spec:
39+
containers:
40+
- name: my-app-b
41+
image: containersol/k8s-deployment-strategies
42+
ports:
43+
- name: http
44+
containerPort: 8080
45+
- name: probe
46+
containerPort: 8086
47+
env:
48+
- name: VERSION
49+
value: v2.0.0
50+
livenessProbe:
51+
httpGet:
52+
path: /live
53+
port: probe
54+
initialDelaySeconds: 5
55+
periodSeconds: 5
56+
readinessProbe:
57+
httpGet:
58+
path: /ready
59+
port: probe
60+
periodSeconds: 5
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
apiVersion: extensions/v1beta1
2+
kind: Ingress
3+
metadata:
4+
name: my-app
5+
labels:
6+
app: my-app
7+
annotations:
8+
kubernetes.io/ingress.class: traefik
9+
spec:
10+
rules:
11+
- host: a.domain.com
12+
http:
13+
paths:
14+
- backend:
15+
serviceName: my-app-a-v1
16+
servicePort: 80
17+
- host: b.domain.com
18+
http:
19+
paths:
20+
- backend:
21+
serviceName: my-app-b-v1
22+
servicePort: 80
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
apiVersion: extensions/v1beta1
2+
kind: Ingress
3+
metadata:
4+
name: my-app
5+
labels:
6+
app: my-app
7+
annotations:
8+
kubernetes.io/ingress.class: traefik
9+
spec:
10+
rules:
11+
- host: a.domain.com
12+
http:
13+
paths:
14+
- backend:
15+
serviceName: my-app-a-v2
16+
servicePort: 80
17+
- host: b.domain.com
18+
http:
19+
paths:
20+
- backend:
21+
serviceName: my-app-b-v2
22+
servicePort: 80

0 commit comments

Comments
 (0)