1、常用部署方案
1.1 滚动更新
滚动更新是一种自动化程度较高的发布方式,用户体验比较平滑,是目前成熟型技术组织所采用的主流发布方式。
优势在于服务不会停止,但是pod会有新旧版本并存的情况。
-
准备YAML文件
- maxSurge 参数详解
- 该值可以是绝对数(例如,5)或所需 Pods 的百分比(例如,10%)。如果
MaxUnavailable
0,则值不能为 0。默认值为 25%。 - 定义除了 replicas 数量之外,在一次滚动更新过程中,Deployment还可以创建多少Pod
- 若设置为30%,则是确保更新期间任何时间运行的 Pods 总数最多为所需 Pods 总数的130%。
- 该值可以是绝对数(例如,5)或所需 Pods 的百分比(例如,10%)。如果
- maxUnavailable 参数详解
- 定义在一次滚动更新过程中,Deployment最多可以删除多少Pod。如果
maxSurge
为 0,则该值不能为 0。默认值为 25%。 - 若设置为30%,确保可用的 Pods 总数在更新期间,任何时候都至少有 70% 所需的 Pods。
- 定义在一次滚动更新过程中,Deployment最多可以删除多少Pod。如果
apiVersion: apps/v1 kind: Deployment metadata: name: rollingupdate spec: strategy: # 策略 rollingUpdate: maxSurge: 1 # 滚动升级时会先启动1个pod maxUnavailable: 2 # 滚动升级时允许的最多不可用的 pod 个数 type: RollingUpdate # 滚动更新升级方式 selector: matchLabels: app: rollingupdate replicas: 4 template: metadata: labels: app: rollingupdate spec: containers: - name: rollingupdate image: registry.cn-hangzhou.aliyuncs.com/zhao_yang/springboot-demo-k8s:v1.0 # 先使用v1.0版本 ports: - containerPort: 8080 --- apiVersion: v1 kind: Service metadata: name: rollingupdate spec: ports: - port: 80 protocol: TCP targetPort: 8080 selector: app: rollingupdate type: ClusterIP
- maxSurge 参数详解
-
创建资源
[root@master-kubeadm-k8s project_deploy]# kubectl apply -f rollingupdate.yaml deployment.apps/rollingupdate created service/rollingupdate created
-
查看资源
[root@master-kubeadm-k8s project_deploy]# kubectl get pods NAME READY STATUS RESTARTS AGE rollingupdate-67cd875cd6-fdxj2 1/1 Running 0 13s rollingupdate-67cd875cd6-r8z7l 1/1 Running 0 13s rollingupdate-67cd875cd6-vwq6b 1/1 Running 0 13s rollingupdate-67cd875cd6-zdfvr 1/1 Running 0 13s [root@master-kubeadm-k8s project_deploy]# kubectl get svc NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE rollingupdate ClusterIP 10.102.255.72
80/TCP 61s -
测试版本
[root@master-kubeadm-k8s project_deploy]# curl 10.102.255.72/k8s hello K8S
-
升级镜像
apiVersion: apps/v1 kind: Deployment metadata: name: rollingupdate spec: strategy: rollingUpdate: maxSurge: 1 maxUnavailable: 2 type: RollingUpdate selector: matchLabels: app: rollingupdate replicas: 4 template: metadata: labels: app: rollingupdate spec: containers: - name: rollingupdate image: registry.cn-hangzhou.aliyuncs.com/zhao_yang/springboot-demo-k8s:v2.0 # 使用v2.0版本 ports: - containerPort: 8080 --- apiVersion: v1 kind: Service metadata: name: rollingupdate spec: ports: - port: 80 protocol: TCP targetPort: 8080 selector: app: rollingupdate type: ClusterIP
-
滚动更新
[root@master-kubeadm-k8s project_deploy]# kubectl apply -f rollingupdate.yaml deployment.apps/rollingupdate configured service/rollingupdate unchanged
-
观察Pod创建过程
-
再次测试
# 现在访问的就是新版本的了 [root@master-kubeadm-k8s project_deploy]# curl 10.102.255.72/k8s hello K8S v2.0
1.2 重新创建
先停止旧的pod,然后再创建新的pod,但这个停止 到 创建新Pod的过程服务是会间断的。
-
准备YAML
apiVersion: apps/v1 kind: Deployment metadata: name: recreate spec: strategy: type: Recreate # 重新创建 selector: matchLabels: app: recreate replicas: 4 template: metadata: labels: app: recreate spec: containers: - name: recreate image: registry.cn-hangzhou.aliyuncs.com/zhao_yang/springboot-demo-k8s:v1.0 ports: - containerPort: 8080 livenessProbe: tcpSocket: port: 8080 --- apiVersion: v1 kind: Service metadata: name: recreate spec: ports: - port: 80 protocol: TCP targetPort: 8080 selector: app: recreate type: ClusterIP
-
创建资源
[root@master-kubeadm-k8s project_deploy]# kubectl apply -f recreate.yaml deployment.apps/recreate created service/recreate created
-
查看资源
[root@master-kubeadm-k8s project_deploy]# kubectl get pods NAME READY STATUS RESTARTS AGE recreate-7b7dbf54cb-6zn2s 1/1 Running 2 118s recreate-7b7dbf54cb-86n84 1/1 Running 2 118s recreate-7b7dbf54cb-d4sw4 1/1 Running 1 118s recreate-7b7dbf54cb-t684d 1/1 Running 1 118s [root@master-kubeadm-k8s project_deploy]# kubectl get svc NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE recreate ClusterIP 10.107.31.94
80/TCP 2m2s -
测试版本
[root@master-kubeadm-k8s project_deploy]# curl 10.107.31.94/k8s hello K8S
-
升级镜像
apiVersion: apps/v1 kind: Deployment metadata: name: recreate spec: strategy: type: Recreate selector: matchLabels: app: recreate replicas: 4 template: metadata: labels: app: recreate spec: containers: - name: recreate image: registry.cn-hangzhou.aliyuncs.com/zhao_yang/springboot-demo-k8s:v2.0 # 升级2.0版本 ports: - containerPort: 8080 livenessProbe: tcpSocket: port: 8080 --- apiVersion: v1 kind: Service metadata: name: recreate spec: ports: - port: 80 protocol: TCP targetPort: 8080 selector: app: recreate type: ClusterIP
-
重新创建
[root@master-kubeadm-k8s project_deploy]# kubectl apply -f recreate.yaml deployment.apps/recreate configured service/recreate unchanged
-
观察Pod创建过程
-
-
再次测试
# 升级成功 [root@master-kubeadm-k8s project_deploy]# curl 10.107.31.94/k8s hello K8S v2.0
1.3 蓝绿部署
V1 版本称为蓝组,V2 版本称为绿组,发布时会一次性将流量从蓝组直接切换到绿组。
蓝绿部署其实就是创建2组Pod同时运行,通过切换Service绑定的标签进行版本切换。无需停机,风险较小。
1.3.1 实际部署流程
- 部署v1的应用(一开始的状态)
- 所有外部请求的流量都打到这个版本上
- 部署v2的应用
- v2的代码与v1不同(新功能、Bug修复等)
- 将流量从v1切换到v2
- 如v2测试正常,就删除v1正在使用的资源(例如实例),从此正式用v2
- 一般不会直接删除v1,因为无法保证v2会在什么时候出现问题
- 当版本升级到v3时,就可以删除v1
1.3.2 开始部署
-
准备YAML文件
service的yaml要与Deployment的yaml分开,这样在升级时才不会修改service-ip
-
bluegreen.yaml
#deploy apiVersion: apps/v1 kind: Deployment metadata: name: blue # 这里的 blue 只是方便观察,实际没意义 spec: strategy: rollingUpdate: # 同样是使用滚动更新的方式 maxSurge: 1 maxUnavailable: 2 type: RollingUpdate selector: matchLabels: app: bluegreen replicas: 4 template: metadata: labels: # 关键点在于这里, 配置2个标签 app: bluegreen # 升级版本时这里不 version: v1.0 # 升级版本时这里更新,Service选择标签也更新,就可以动态的切换到新版本 spec: containers: - name: bluegreen image: registry.cn-hangzhou.aliyuncs.com/zhao_yang/springboot-demo-k8s:v1.0 ports: - containerPort: 8080
-
bluegreen-service.yaml
apiVersion: v1 kind: Service metadata: name: bluegreen-service spec: ports: - port: 80 protocol: TCP targetPort: 8080 selector: app: bluegreen version: v1.0 # 当版本升级时,修改版本即可动态升级版本,这样service-IP不会变 type: ClusterIP
-
-
创建资源
[root@master-kubeadm-k8s project_deploy]# kubectl apply -f bluegreen.yaml deployment.apps/blue created [root@master-kubeadm-k8s project_deploy]# kubectl apply -f bluegreen-service.yaml service/bluegreen-service created
-
查看资源
[root@master-kubeadm-k8s project_deploy]# kubectl get pods NAME READY STATUS RESTARTS AGE blue-8675d5c885-75shf 1/1 Running 0 2m43s blue-8675d5c885-j2qmm 1/1 Running 0 2m44s blue-8675d5c885-m9z2s 1/1 Running 0 2m44s blue-8675d5c885-x6ht4 1/1 Running 0 2m44s [root@master-kubeadm-k8s project_deploy]# kubectl get svc NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE bluegreen-service ClusterIP 10.111.118.191
80/TCP 2m44s -
测试版本
[root@master-kubeadm-k8s project_deploy]# curl 10.111.118.191/k8s hello K8S
-
升级镜像
-
bluegreen.yaml
#deploy apiVersion: apps/v1 kind: Deployment metadata: name: green # 修改名称为 green 只是方便观察,实际没意义 spec: strategy: rollingUpdate: maxSurge: 1 maxUnavailable: 2 type: RollingUpdate selector: matchLabels: app: bluegreen replicas: 4 template: metadata: labels: app: bluegreen version: v2.0 # 升级版本 spec: containers: - name: bluegreen image: registry.cn-hangzhou.aliyuncs.com/zhao_yang/springboot-demo-k8s:v2.0 # 升级镜像版本 ports: - containerPort: 8080
-
bluegreen-service.yaml
apiVersion: v1 kind: Service metadata: name: bluegreen-service spec: ports: - port: 80 protocol: TCP targetPort: 8080 selector: app: bluegreen version: v2.0 # 选择新版本的Pod type: ClusterIP
-
-
重新创建
[root@master-kubeadm-k8s project_deploy]# kubectl apply -f bluegreen.yaml deployment.apps/green created [root@master-kubeadm-k8s project_deploy]# kubectl apply -f bluegreen-service.yaml service/bluegreen-service configured
-
观察Pod
-
再次测试
# 切换成功 [root@master-kubeadm-k8s project_deploy]# curl 10.111.118.191/k8s hello K8S v2.0
如果发现这个版本有问题,那么直接修改service中的标签选择器为 v1.0 版本即可
1.4 金丝雀部署
金丝雀部署也叫AB测试(国内称灰度发布),是指会有2个版本的代码存在,目的是先让一部分用户来测试新功能,若新功能没问题,再全部升级为新版本的功能。
这里要使用的话可以直接使用上面的YAML文件,只需修改bluegreen-service.yaml文件中的标签选择器即可!
-
修改service的YAML文件
apiVersion: v1 kind: Service metadata: name: bluegreen-service spec: ports: - port: 80 protocol: TCP targetPort: 8080 selector: app: bluegreen # version: v2.0 # 取消版本选择,让2个版本的Pod都运用起来 type: ClusterIP
-
更新资源
[root@master-kubeadm-k8s project_deploy]# kubectl apply -f bluegreen-service.yaml service/bluegreen-service configured
-
测试
这样就达到了AB测试的功能,两个版本共存
[root@master-kubeadm-k8s project_deploy]# while sleep 0.5; do curl 10.111.118.191/k8s; echo "";done hello K8S hello K8S hello K8S v2.0 hello K8S hello K8S v2.0 hello K8S hello K8S hello K8S v2.0 hello K8S hello K8S hello K8S hello K8S v2.0 hello K8S v2.0 hello K8S v2.0 hello K8S v2.0 hello K8S v2.0 # ...
如果想要让更少部分用户体验新版的功能,那修改新版本的YAML文件时,可以将副本数改的少点就可以了