kubernetes-部署策略
Kubernetes的部署策略以下几种:
- 重建(recreate):停止旧版本部署新版本
- 滚动更新(rolling-update):一个接一个地以滚动更新方式发布新版本
- 蓝绿(blue/green):新版本与旧版本一起存在,然后切换流量
- 金丝雀(canary):将新版本面向一部分用户发布,然后继续全量发布
重建(Recreate)
特点 : 停止旧版本部署新版本
使用场景 : 最好在开发环境
yaml
(版本A)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
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60#deploy
apiVersion: apps/v1
kind: Deployment
metadata:
name: web-recreate
namespace: dev
spec:
selector:
matchLabels:
app: web-recreate
replicas: 2 # 部署两个pod
template:
metadata:
labels:
app: web-recreate
spec:
containers:
- name: web-recreate
image: tomcat:8-slim
ports:
- containerPort: 8080
livenessProbe:
tcpSocket:
port: 8080
initialDelaySeconds: 20
periodSeconds: 10
failureThreshold: 2
successThreshold: 1
#service
apiVersion: v1
kind: Service
metadata:
name: web-recreate
namespace: dev
spec:
ports:
- port: 80
protocol: TCP
targetPort: 8080
selector:
app: web-recreate
type: ClusterIP
#ingress
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: web-recreate
namespace: dev
spec:
rules:
- host: web-recreate.chc.com
http:
paths:
- path: /
backend:
serviceName: web-recreate
servicePort: 80在访问服务的机器上配置hosts:
192.168.43.113 web-recreate.chc.com
,然后通过web-recreate.chc.com
域名访问yaml
(版本B)使用Recreate策略更新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
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63#deploy
apiVersion: apps/v1
kind: Deployment
metadata:
name: web-recreate
namespace: dev
spec:
strategy: # 部署策略声明
type: Recreate # 使用Recreate策略
selector:
matchLabels:
app: web-recreate
replicas: 2 # 部署两个pod
template:
metadata:
labels:
app: web-recreate
type: web-app # 更新内容为:加多一个标签type
spec:
containers:
- name: web-recreate
image: tomcat:8-slim
ports:
- containerPort: 8080
livenessProbe:
tcpSocket:
port: 8080
initialDelaySeconds: 20
periodSeconds: 10
failureThreshold: 2
successThreshold: 1
#service
apiVersion: v1
kind: Service
metadata:
name: web-recreate
namespace: dev
spec:
ports:
- port: 80
protocol: TCP
targetPort: 8080
selector:
app: web-recreate
type: ClusterIP
#ingress
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: web-recreate
namespace: dev
spec:
rules:
- host: web-recreate.chc.com
http:
paths:
- path: /
backend:
serviceName: web-recreate
servicePort: 80重新创建策略是一个虚拟部署,包括关闭版本A,然后在关闭版本A后部署版本B. 此技术意味着服务的停机时间取决于应用程序的关闭和启动持续时间。
滚动更新(rolling-update)
特点 : 滚动更新通过逐个替换实例来逐步部署新版本的应用,直到所有实例都被替换完成为止.更新过程中新旧服务同时可以访问
更新的过程 : 在负载均衡器后面使用版本 A 的实例池,然后部署版本 B 的一个实例,当服务准备好接收流量时(Readiness Probe 正常),将该实例添加到实例池中,然后从实例池中删除一个版本 A 的实例并关闭
yaml
(版本A)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
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61#deploy
apiVersion: apps/v1
kind: Deployment
metadata:
name: web-rollingupdate
namespace: dev
spec:
selector:
matchLabels:
app: web-rollingupdate
replicas: 2
template:
metadata:
labels:
app: web-rollingupdate
spec:
containers:
- name: web-rollingupdate
image: tomcat:8-slim
ports:
- containerPort: 8080
livenessProbe:
tcpSocket:
port: 8080
initialDelaySeconds: 20
periodSeconds: 10
failureThreshold: 3
successThreshold: 1
timeoutSeconds: 5
#service
apiVersion: v1
kind: Service
metadata:
name: web-rollingupdate
namespace: dev
spec:
ports:
- port: 80
protocol: TCP
targetPort: 8080
selector:
app: web-rollingupdate
type: ClusterIP
#ingress
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: web-rollingupdate
namespace: dev
spec:
rules:
- host: web-rollingupdate.chc.com
http:
paths:
- path: /
backend:
serviceName: web-rollingupdate
servicePort: 80在访问服务的机器上配置hosts:
192.168.43.113 web-rollingupdate.chc.com
,然后通过web-recreate.chc.com
域名访问yaml
(版本B)使用rolling-update策略更新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
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67#deploy
apiVersion: apps/v1
kind: Deployment
metadata:
name: web-rollingupdate
namespace: dev
spec:
strategy: # 声明使用部署策略
type: RollingUpdate # 使用RollingUpdate策略来更新pod
rollingUpdate: # RollingUpdate策略配置
maxSurge: 50% # 一次可以添加50%个Pod
maxUnavailable: 50% # 滚动更新期间最大50%个Pod不可用
selector:
matchLabels:
app: web-rollingupdate
replicas: 2
template:
metadata:
labels:
app: web-rollingupdate
type: web-app2 # 更新内容为:加多一个标签type
spec:
containers:
- name: web-rollingupdate
image: tomcat:9-slim # 更新tomcat版本
ports:
- containerPort: 8080
livenessProbe:
tcpSocket:
port: 8080
initialDelaySeconds: 20
periodSeconds: 10
failureThreshold: 3
successThreshold: 1
timeoutSeconds: 5
#service
apiVersion: v1
kind: Service
metadata:
name: web-rollingupdate
namespace: dev
spec:
ports:
- port: 80
protocol: TCP
targetPort: 8080
selector:
app: web-rollingupdate
type: ClusterIP
#ingress
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: web-rollingupdate
namespace: dev
spec:
rules:
- host: web-rollingupdate.chc.com
http:
paths:
- path: /
backend:
serviceName: web-rollingupdate
servicePort: 80可以使用
kuectl rollout pause deploy [deployments] -n [namespaces]
命令暂停滚动从而让新旧服务同时存在,来进行测试然后使用
kuectl rollout resume deploy [deployments] -n [namespaces]
恢复滚动操作回滚到上个版本:
kuectl rollout undo deploy [deployments] -n [namespaces]
rollingUpdate
配置说明参数 说明 maxSurge 一次更新pod的数量可以使用百分比%,也可以使用数量 maxUnavailable 滚动更新期间最大不可用Pod数量,可以用百分比%,也可以使用数量 资源部署操作
kuectl rollout
命令 作用 history 查看历史版本 pause 暂停资源(可以暂停滚动更新) resume 恢复暂停资源 status 查看资源状态 undo 回滚版本
蓝绿(blue/green)
特点 :版本2(
绿
) 与版本1(蓝
)一起部署,在测试新版本满足要求后,然后更新更新 Kubernetes 中扮演负载均衡器角色的 Service 对象,通过替换 label selector 中的版本标签来将流量发送到新版本web-bluegreen.yaml
(版本 1)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#deploy
apiVersion: apps/v1
kind: Deployment
metadata:
name: web-bluegreen
namespace: dev
spec:
strategy: # 声明使用部署策略
type: RollingUpdate # 使用RollingUpdate策略来更新pod
rollingUpdate: # RollingUpdate策略配置
maxSurge: 50% # 一次可以添加50%个Pod
maxUnavailable: 50% # 滚动更新期间最大50%个Pod不可用
selector:
matchLabels:
app: web-bluegreen
replicas: 2
template:
metadata:
labels:
# 这里标签注明app名字和版本号
app: web-bluegreen
version: v1.0
spec:
containers:
- name: web-bluegreen
image: tomcat:8-slim
ports:
- containerPort: 8080
livenessProbe:
tcpSocket:
port: 8080
initialDelaySeconds: 20
periodSeconds: 10
failureThreshold: 3
successThreshold: 1
timeoutSeconds: 5bluegreen-service.yaml
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
#service
apiVersion: v1
kind: Service
metadata:
name: web-bluegreen
namespace: dev
spec:
ports:
- port: 80
protocol: TCP
targetPort: 8080
selector:
# 这里匹配 app 和 version 标签,当要切换流量的时候,我们更新 version 标签的值,比如:v2.0
app: web-bluegreen
version: v1.0
type: ClusterIP
#ingress
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: web-bluegreen
namespace: dev
spec:
rules:
- host: web-bluegreen.chc.com
http:
paths:
- path: /
backend:
serviceName: web-bluegreen
servicePort: 80web-bluegreen2.yaml
(版本2)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#deploy
apiVersion: apps/v1
kind: Deployment
metadata:
name: web-bluegreen-v2 # 新版本的名称
namespace: dev
spec:
strategy: # 声明使用部署策略
type: RollingUpdate # 使用RollingUpdate策略来更新pod
rollingUpdate: # RollingUpdate策略配置
maxSurge: 50% # 一次可以添加50%个Pod
maxUnavailable: 50% # 滚动更新期间最大50%个Pod不可用
selector:
matchLabels:
app: web-bluegreen
replicas: 2
template:
metadata:
labels:
app: web-bluegreen
version: v2.0 #标签的version变为v2.0
spec:
containers:
- name: web-bluegreen
image: tomcat:9-slim # 升级tomcat
ports:
- containerPort: 8080
livenessProbe:
tcpSocket:
port: 8080
initialDelaySeconds: 20
periodSeconds: 10
failureThreshold: 3
successThreshold: 1
timeoutSeconds: 5bluegreen-service.yaml
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
#service
apiVersion: v1
kind: Service
metadata:
name: web-bluegreen
namespace: dev
spec:
ports:
- port: 80
protocol: TCP
targetPort: 8080
selector:
# 这里匹配 app 和 version 标签,当要切换流量的时候,我们更新 version 标签的值
app: web-bluegreen
version: v2.0 # 切换流量到v2.0版本
type: ClusterIP
#ingress
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: web-bluegreen
namespace: dev
spec:
rules:
- host: web-bluegreen.chc.com
http:
paths:
- path: /
backend:
serviceName: web-bluegreen
servicePort: 80蓝/绿部署步骤:
- 部署版本1的yaml:
kubectl apply -f web-bluegreen.yaml
- 部署service的yaml:
kubectl apply -f bluegreen-service.yaml
- 部署版本2的yaml :
kubectl apply -f web-bluegreen2.yaml
- 等待版本2的全部部署完成
- 切换流量入口从版本1到版本2 (这里就是将service的yaml的version标签改成v2.0):
kubectl apply -f bluegreen-service.yaml
- 关闭版本1的应用 :
kubectl delete deployments -n dev web-bluegreen
- 部署版本1的yaml:
优缺点:
- 实时部署/回滚
- 避免版本问题,因为一次更改是整个应用的改变
- 需要两倍的资源
- 在发布到生产之前,应该对整个应用进行适当的测试
金丝雀(Canary)
特点:金丝雀部署是让部分用户访问到新版本应用,在一段时间后如果没有检测到错误,则可以扩展新版本的副本数量并删除旧版本的应用。
部署方式参照蓝/绿部署的yaml文件
- 部署版本1
web-bluegreen.yaml
- 部署版本2
web-bluegreen2.yaml
- 将
bluegreen-service.yaml
中的version
标签去掉 - 部署service服务
bluegreen-service.yaml
- 如果版本2的pod没问题,逐步替换版本1为版本2
- 部署版本1
优缺点
- 部分用户获取新版本
- 方便错误发现和性能监控
- 快速回滚
- 发布较慢
- 流量精准控制很浪费
建议:使用服务网格(如 Istio)来构建金丝雀部署,拥有更精准的流量控制