kubernetes云原生纪元:部署策略实战-滚动、重建、蓝绿、金丝雀
原生的kuberntes 部署策略
-
Rolling update 滚动更新
-
Recreate 重新创建
利用Service 的一些特征label Selector 的机制结合Deploymet 一起去完成的部署方式
-
蓝绿部署 利用service 的selector 选择不同版本的服务
-
金丝雀
Recreate重建策略
在Deployment 配置
spec:
strategy:
type: Recreate #部署类型 重建
完整的配置如下:
Web-recreate.yaml
#deploy
apiVersion: apps/v1
kind: Deployment
metadata:
name: web-recreate
namespace: dev
spec:
strategy:
type: Recreate
selector:
matchLabels:
app: web-recreate
type: webapp
replicas: 2 #两个实例
template:
metadata:
labels:
app: web-recreate
type: webapp
spec:
containers:
- name: web-recreate
image: hub.zhang.com/kubernetes/demo:2020011512381579063123
ports:
- containerPort: 8080
---
#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.demo.com
http:
paths:
- path: /
backend:
serviceName: web-recreate
servicePort: 80
我们先创建下:
[root@master-001 ~]# kubectl apply -f web-recreate.yaml
deployment.apps/web-recreate created
service/web-recreate created
ingress.extensions/web-recreate created
[root@master-001 ~]# kubectl get pod #运行了两个实例
NAME READY STATUS RESTARTS AGE
web-recreate-754fcc6cd-dspr6 1/1 Running 0 8m45s
web-recreate-754fcc6cd-pr4kx 1/1 Running 0 8m45s
创建成功访问下:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ozpNCCbB-1580786400016)(/Users/zck/Library/Application Support/typora-user-images/image-20200123104737960.png)]
假如我们现在修改了一下配置文件web-recreate.yaml
然后重新创建,查看下发现之前的正在停止
停止了以后再启动了两个新的
由此可见它是先停掉旧的pod 再启动新的,这样部署策略服务是间断的
使用场景:资源不是太充足的时候,一个服务运行了两个实例,这五个实例不在同一个节点上的,我们在测试的时候为了快速的重启,我们就可以使用这种方式,他可以把这些实例全部重启
Rolling update 滚动部署
基本配置:
spec:
strategy:
rollingUpdate:
maxSurge: 25% #最大可以超出服务实例数的百分比。比如有四个实例,25%就是1个实例,每次最多多启动一个实例
maxUnavailable: 25% #最大不可用服务实例数的百分比。可以容忍25% 的实例是不可用的,比如四个实例只能有一个不可用,三个必须可以
type: RollingUpdate # 滚动更新
为什么kubernetes 没有配置部署策略默认也滚动更新,而且配置跟我们这里一样
#maxSurge maxUnavailable也可以通过数值配置 写1=1个实例
完整配置如下:
web-rollingUpdate.yaml
#deploy
apiVersion: apps/v1
kind: Deployment
metadata:
name: web-rollingUpdate
namespace: dev
spec:
strategy:
rollingUpdate:
maxSurge: 25% #最大可以超出服务实例数的百分比。比如有四个实例,25%就是1个实例,每次最多多启动一个实例
maxUnavailable: 25% #最大不可用服务实例数的百分比。可以容忍25% 的实例是不可用的,比如四个实例只能有一个不可用,三个必须可以
type: RollingUpdate # 滚动更新 为什么kubernetes 没有配置部署策略默认也滚动更新,而且配置跟我们这里一样
selector:
matchLabels:
app: web-rollingUpdate
type: webapp
replicas: 2 #两个实例
template:
metadata:
labels:
app: web-rollingUpdate
type: webapp
spec:
containers:
- name: web-rollingUpdate
image: hub.zhang.com/kubernetes/demo:2020011512381579063123
ports:
- containerPort: 8080
---
#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.demo.com
http:
paths:
- path: /
backend:
serviceName: web-rollingUpdate
servicePort: 80
这里不做演示了,原理是,服务访问不会间断,部署期间会间隔的来回切换访问新服务和老服务,等到新服务完全正常,就停止掉了老服务
我们可以通过暂停服务
[root@master-001 ~] kubectl rollout pause deploy ${deploy名字}
测试服务然后再放开继续部署
[root@master-001 ~] kubectl rollout resume deploy ${deploy名字}
如果我们想回退
到上个版本
[root@master-001 ~] kubectl rollout undo deploy ${deploy名字}
上面讲的全依靠修改deployment的配置进行部署,利用deployment自己支持的方式,下面讲下更高级的部署方式。
蓝绿部署
保持原有的deployment不动,可以是Recreate,也可以是Rolling update ,在原有的deployment之上,新建一个deployment,原有的是蓝色的,新建是绿色的,通过测试没有问题,修改service selector 把流量接到新建的这一边
首先有一个蓝色 deploy
web-blue.yaml
#deploy
apiVersion: apps/v1
kind: Deployment
metadata:
name: web-bluegreen
namespace: dev
spec:
strategy:
rollingUpdate:
maxSurge: 25%
maxUnavailable: 25%
type: RollingUpdate
selector:
matchLabels:
app: web-bluegreen
replicas: 1
template:
metadata:
labels:
app: web-bluegreen
version: v1.0
spec:
containers:
- name: web-bluegreen
image: hub.zhang.com/kubernetes/spring-boot-demo:2020011512381579063123
ports:
- containerPort: 8080
创建下:
[root@master-001 ~]# kubectl apply -f web-bluegreen.yaml
deployment.apps/web-bluegreen created
还有个service
bluegreen-service.yaml
#service
apiVersion: v1
kind: Service
metadata:
name: web-bluegreen
namespace: dev
spec:
ports:
- port: 80
protocol: TCP
targetPort: 8080
selector: # 标签app=web-bluegreen 并且version=v1.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.demo.com
http:
paths:
- path: /
backend:
serviceName: web-bluegreen
servicePort: 80
我们先创建下service
[root@master-001 ~]# kubectl apply -f bluegreen-service.yaml
service/web-bluegreen created
ingress.extensions/web-bluegreen created
我们直接访问是访问的web-bluegreen.yaml
的部署服务,
再创建一个绿色deployweb-green.yaml
#deploy
apiVersion: apps/v1
kind: Deployment
metadata:
name: web-green
namespace: dev
spec:
strategy:
rollingUpdate:
maxSurge: 25%
maxUnavailable: 25%
type: RollingUpdate
selector:
matchLabels:
app: web-bluegreen
replicas: 2 #两个实例
template:
metadata:
labels:
app: web-bluegreen
version: v2.0 #修改版本
spec:
containers:
- name: web-bluegreen
image: hub.zhang.com/kubernetes/demo:2020011512381579063123 #修改新的镜像
ports:
- containerPort: 8080
[root@master-001 ~]# kubectl apply -f web-bluegreen-v2.yaml
deployment.apps/web-bluegreen-v2 created
重点来了
修改service 切换流量改成version: v2.0
[root@master-001 ~]# vi bluegreen-service.yaml
#service
apiVersion: v1
kind: Service
metadata:
name: web-bluegreen
namespace: dev
spec:
ports:
- port: 80
protocol: TCP
targetPort: 8080
selector: # 标签app=web-bluegreen 并且version=v1.0
app: web-bluegreen
version: v2.0 #改成2.0
type: ClusterIP
.....
[root@master-001 ~]# kubectl apply -f bluegreen-service.yaml #重新创建下
service/web-bluegreen configured
ingress.extensions/web-bluegreen unchanged
查看我们的访问结果
从之前的deploy v1.0 变成了现在deployv2.0 新版本的了,而且没有交替的过程
而且上个版本还在
[root@master-001 ~]# kubectl get pod
NAME READY STATUS RESTARTS AGE
web-blue-9668758db-vr26g 1/1 Running 0 15m
web-green-5f7d8fb8f9-82fbh 1/1 Running 0 7m44s
总结: 蓝绿部署的意思是原来的我们叫它是蓝色的版本,我们新建的这个叫绿色的版本,两个不同的版本是交替的,如果我的新版本有问题,可以直接修改service的selector version:v1.0,就会立刻切换回来,一般旧版会随着新版本运行一段时间,确定没有问题了我们才可以把旧版本删掉。
金丝雀部署
在蓝绿部署之上我们简单修改下service selector就变成了金丝雀部署
使用 蓝绿部署的service和deployment 配置
去掉service 的selector version: v2.0
[root@master-001 ~]# vi web-bluegreen-v2.yaml
#service
apiVersion: v1
kind: Service
metadata:
name: web-bluegreen
namespace: dev
spec:
ports:
- port: 80
protocol: TCP
targetPort: 8080
selector: # 标签app=web-bluegreen 并且version=v1.0
app: web-bluegreen
version: v2.0 #改成2.0
type: ClusterIP
.....
[root@master-001 ~]# kubectl apply -f bluegreen-service.yaml #重新创建下
service/web-bluegreen configured
ingress.extensions/web-bluegreen unchanged
再次访问:
发现两个服务之间进行不断的交替了
因为现在我们的service可以选中所有的标签为app=bulegreen
的服务,可以访问一个多个,比如我现在做一个新功能并不确定我这个功能不是特别的好用,现在有十个实例,我现在新创建的只有一个实例,那它的流量只有10%,从使这个小功能在不影响大量用户的情况下完成一个实验,也就是我们常说的ab测试。
ab测试流量分发如果我们配合Istio会更好的完成这方面的工作,我们现在说的只是一个成人版
的,可以用于简单工作。
Istio 的发音是“一丝踢藕”,重音在前