kubernetes云原生纪元:部署策略实战-滚动、重建、蓝绿、金丝雀

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

然后重新创建,查看下发现之前的正在停止

image-20200126102555850

停止了以后再启动了两个新的

image-20200126102910689

image-20200126103037194

由此可见它是先停掉旧的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名字}

image-20200126111217116

如果我们想回退到上个版本

[root@master-001 ~] kubectl rollout undo deploy ${deploy名字}

image-20200126112018135

上面讲的全依靠修改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的部署服务,

image-20200126115010361

再创建一个绿色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 新版本的了,而且没有交替的过程

image-20200126120030356

而且上个版本还在

[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

再次访问:

发现两个服务之间进行不断的交替了

image-20200126121531159

因为现在我们的service可以选中所有的标签为app=bulegreen的服务,可以访问一个多个,比如我现在做一个新功能并不确定我这个功能不是特别的好用,现在有十个实例,我现在新创建的只有一个实例,那它的流量只有10%,从使这个小功能在不影响大量用户的情况下完成一个实验,也就是我们常说的ab测试。

ab测试流量分发如果我们配合Istio会更好的完成这方面的工作,我们现在说的只是一个成人版的,可以用于简单工作。

Istio 的发音是“一丝踢藕”,重音在前

发布了20 篇原创文章 · 获赞 3 · 访问量 590

猜你喜欢

转载自blog.csdn.net/weixin_37546425/article/details/104166866