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

  1. The application state is updated all at once.
  2. Downtime depends on the time consumed by application shutdown and startup.
  3. 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

  1. Slow update of application status (updated with the regularity of new version added and old version exited).
  2. No downtime.
  3. no control over whether the traffic is in a new version or an old version.
  4. 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

  1. The application status is updated at once and the version switching is fast.
  2. No downtime.
  3. Small deployment/rollback traffic switching interval.
  4. Twice the resources are required.
  5. 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

  1. Slow application status updates (old and new version traffic share).
  2. no downtime.
  3. Small deployment/rollback traffic switching interval.
  4. slower release.
  5. there is some traffic distribution.
  6. Some users get new versions.
  7. easy error and performance monitoring.