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