This article describes the main Release Policies for k8s applications.
Recreate
Stop the old version and deploy the new one.
Main Configuration
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
|
---
kind: Service
apiVersion: v1
metadata:
name: test-app
labels:
app: test-app
spec:
type: NodePort
ports:
- name: http
port: 80
targetPort: http
selector: # 匹配 pod 的标签
app: test-app
---
Kind: Deployment
apiVersion: apps/v1
metadata:
name: test-app
spec:
replicas: 3
strategy:
type: Recreate # 重建策略
selector:
matchLabels: # 匹配 pod 的标签
app: test-app
template:
metadata:
labels: # pod 标签
app: test-app
version: v1.0.0 # 版本标签
|
Operation process
1
2
3
4
5
6
7
8
9
10
11
12
13
|
# 1. 部署 v1.0.0 版本应用
kubectl apply -f app-v1.0.0.yaml
# 2. 观察 pod 情况
kubectl get pods --show-labels -l app=test-app
# 3. 部署 v2.0.0 版本应用
kubectl apply -f app-v2.0.0.yaml # version 变动
# 4. 观察 pod 情况
kubectl get pods --show-labels -l app=test-app
# 这时发现之前的 pod 全部处于 Terminating 状态, 待 v1.0.0 版本的pod删除完,才会新建 v2.0.0 的 pod 。
|
Summary
- The application state is updated all at once.
- Downtime depends on the time consumed by application shutdown and startup.
- Deployment rollback takes longer.
Rolling-update
Release new versions one after another as rolling-updates.
Main Configuration
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
|
---
kind: Service
apiVersion: v1
metadata:
name: test-app
labels:
app: test-app
spec:
type: NodePort
ports:
- name: http
port: 80
targetPort: http
selector: # 匹配 pod 的标签
app: test-app
---
Kind: Deployment
apiVersion: apps/v1
metadata:
name: test-app
spec:
replicas: 3
strategy:
type: RollingUpdate # 滚动更新
rollingUpdate:
maxSurge: 1 # 一次可以添加多少个Pod
maxUnavailable: 1 # 滚动更新期间最大多少个Pod不可用
selector:
matchLabels: # 匹配 pod 的标签
app: test-app
template:
metadata:
labels: # pod 标签
app: test-app
version: v1.0.0 # 版本标签
|
Operation process
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
|
# 1. 部署 v1.0.0 版本应用
kubectl apply -f app-v1.0.0.yaml
# 2. 观察 pod 情况
kubectl get pods --show-labels -l app=test-app
# 3. 部署 v2.0.0 版本应用
kubectl apply -f app-v2.0.0.yaml # version 变动
# 4. 观察 pod 情况
kubectl get pods --show-labels -l app=test-app
# 这时发现 v1.0.0 版本的 pod 有一个处于 Terminating 状态, 其他的 pod 都是 Running 。
# 有 2 个 v2.0.0 的 POD 被创建(maxSurge 为1,在同一时间内可允许最多4个pod 为 Running,但是当前只有2个pod 为 Running)。
# 待 v2.0.0 的 POD 都为 READY 时,v1.0.0 版本的 pod 将也都会被相继删掉。
|
Summary
- Slow update of application status (updated with the regularity of new version added and old version exited).
- No downtime.
- no control over whether the traffic is in a new version or an old version.
- Deployment rollback rollout/rollback takes some time.
Blue/Green
New version exists with old version, then switch traffic.
Main Configuration
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
|
---
kind: Service
apiVersion: v1
metadata:
name: test-app
labels:
app: test-app
spec:
type: NodePort
ports:
- name: http
port: 80
targetPort: http
selector: # 匹配 pod 的标签
app: test-app
version: v1.0.0 # 版本标签
---
Kind: Deployment
apiVersion: apps/v1
metadata:
name: test-app
spec:
replicas: 3
strategy:
type: RollingUpdate # 滚动更新
rollingUpdate:
maxSurge: 2 # 一次可以添加多少个Pod
maxUnavailable: 1 # 滚动更新期间最大多少个Pod不可用
selector:
matchLabels: # 匹配 pod 的标签
app: test-app
version: v1.0.0 # 版本标签
template:
metadata:
labels: # pod 标签
app: test-app
version: v1.0.0 # 版本标签
|
Operation process
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
|
# 1. 部署 v1.0.0 版本应用
kubectl apply -f app-v1.0.0.yaml
# 2. 观察 pod 情况
kubectl get pods --show-labels -l app=test-app
# 3. 部署 v2.0.0 版本应用
kubectl apply -f app-v2.0.0.yaml # version 变动, name 也变动。
# 4. 观察 pod 情况
kubectl get pods --show-labels -l app=test-app
# 这时发现 v1.0.0 和 v2.0.0 版本的 pod 状态 都是 Running 。
# 5. 切换流量
kubectl patch service test-app -p '{"spec":{"selector":{"version":"v2.0.0"}}}'
# 这时再去访问流量,都是 v2.0.0 的了。
|
Summary
- The application status is updated at once and the version switching is fast.
- No downtime.
- Small deployment/rollback traffic switching interval.
- Twice the resources are required.
- The entire application should be properly tested before releasing to production
Canary
Release the new version to a subset of users, then continue with the full release.
Main Configuration
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
|
---
kind: Service
apiVersion: v1
metadata:
name: test-app
labels:
app: test-app
spec:
type: NodePort
ports:
- name: http
port: 80
targetPort: http
selector: # 匹配 pod 的标签
app: test-app
---
Kind: Deployment
apiVersion: apps/v1
metadata:
name: test-app
spec:
replicas: 3
strategy:
type: RollingUpdate # 滚动更新
rollingUpdate:
maxSurge: 2 # 一次可以添加多少个Pod
maxUnavailable: 1 # 滚动更新期间最大多少个Pod不可用
selector:
matchLabels: # 匹配 pod 的标签
app: test-app
version: v1.0.0 # 版本标签
template:
metadata:
labels: # pod 标签
app: test-app
version: v1.0.0 # 版本标签
|
Operation process
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
|
# 1. 部署 v1.0.0 版本应用
kubectl apply -f app-v1.0.0.yaml
# 2. 观察 pod 情况
kubectl get pods --show-labels -l app=test-app
kubectl describe svc test-app
# 3. 部署 v2.0.0 版本应用
kubectl apply -f app-v2.0.0.yaml # version 变动, name 也变动。
# 4. 观察 pod 情况
kubectl get pods --show-labels -l 'app in (test-app, test-app2)'
kubectl describe svc test-app
# 这时发现 v1.0.0 和 v2.0.0 版本的 pod 状态 都是 Running 。
# 且 service 下的 pod 有 6个, 两个版本的流量是 1:1 。
# 5. 切换流量
kubectl scale --replicas=2 deploy test-app
# 这是,缩小 test-app(v1.0.0) 版本的 pod 副本, 两个版本的流量是 4:6 了。
# 6. 在缩小v1流量
kubectl scale --replicas=1 deploy test-app
# 这是,缩小 test-app(v1.0.0) 版本的 pod 副本, 两个版本的流量是 2.5:7.5 了。
# 通过这种方式,来调整 v1.0.0 和 v2.0.0 版本的 pod 副本,从而达到控制流量分配。
|
Summary
- Slow application status updates (old and new version traffic share).
- no downtime.
- Small deployment/rollback traffic switching interval.
- slower release.
- there is some traffic distribution.
- Some users get new versions.
- easy error and performance monitoring.