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 的發音是“一絲踢藕”,重音在前

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章