常見的部署方案:
- 滾動更新:服務不會中止,可是整個pod會有新舊並存的狀況。
- 從新建立:先中止舊的pod,而後再建立新的pod,這個過程服務是會間斷的。
- 藍綠部署:無需停機,風險較小。部署v1的應用(一開始的狀態)全部外部請求的流量都打到這個版本上。部署版本2的應用版本2的代碼與版本1不一樣(新功能、Bug修復等)。將流量從版本1切換到版本2。如版本2測試正常,就刪除版本1正在使用的資源(例如實例),今後正式用版本2。
- 金絲雀部署:金絲雀發佈通常先發 1 臺,或者一個小比例,例如 2% 的服務器,主要作流量驗證用,也稱爲金絲雀 (Canary) 測試(國內常稱灰度測試)。之前曠工開礦下礦洞前,先會放一隻金絲雀進去探是否有有毒氣體,看金絲雀可否活下來,金絲雀發佈由此得名。簡單的金絲雀測試通常經過手工測試驗證,複雜的金絲雀測試 須要比較完善的監控基礎設施配合,經過監控指標反饋,觀察金絲雀的健康情況,做爲後續發佈或回退的依據。若是金絲測試經過,則把剩餘的 V1 版本所有升級爲 V2 版本。若是金絲雀測試失敗,則直接回退金絲雀,發佈失敗。
滾動更新:
建立 rollingupdate.yaml 文件:html
maxUnavailable:最大無效pod數。
maxSurge:最大激增pod數。docker
apiVersion: apps/v1 kind: Deployment metadata: name: rollingupdate spec: strategy: rollingUpdate: maxSurge: 25% maxUnavailable: 25% type: RollingUpdate selector: matchLabels: app: rollingupdate replicas: 4 template: metadata: labels: app: rollingupdate spec: containers: - name: rollingupdate image: registry.cn-hangzhou.aliyuncs.com/wuzz-docker/test-docker-image: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
kubectl apply -f rollingupdate.yaml
kubectl get pods
kubectl get svc
curl svc r-ip/dockerfileapi
修改rollingupdate.yaml文件,將鏡像修改爲v2.0服務器
# 在w1上,不斷地訪問觀察輸出 while sleep 0.2;do curl cluster-ip/dockerfile;echo "";done # 在w2上,監控pod kubectl get pods -w # 使得更改生效 kubectl apply -f rollingupdate.yaml kubectl get pods
發現新舊pod是會共存的,而且能夠訪問測試看一下app
從新建立:
建立 recreate.yaml 文件curl
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/wuzz-docker/test-docker-image:v1.0 ports: - containerPort: 8080 livenessProbe: tcpSocket: port: 8080
kubectl apply -f recreate.yamltcp
kubectl get podside
修改recreate.yaml文件 改爲 v2.0,執行kubectl apply -f recreate.yaml使其生效。同時在w2上進行觀察 kubectl get pods -w 。發現pod是先中止,而後再建立新的測試
Have a tryurl
kubectl rollout pause deploy/deploy-name #暫停資源 kubectl rollout resume deploy/rollingupdate #回覆暫停資源 kubectl rollout undo deploy/rollingupdate --to-revision=2 # 回到上一個版本
藍綠部署:
建立 bluegreen.yaml :
#deploy apiVersion: apps/v1 kind: Deployment metadata: name: blue spec: strategy: rollingUpdate: maxSurge: 25% maxUnavailable: 25% type: RollingUpdate selector: matchLabels: app: bluegreen replicas: 4 template: metadata: labels: app: bluegreen version: v1.0 spec: containers: - name: bluegreen image: registry.cn-hangzhou.aliyuncs.com/wuzz-docker/test-docker-image:v1.0 ports: - containerPort: 8080
kubectl apply -f bluegreen.yaml
kubectl get pods
建立 bluegreen-service.yaml :
apiVersion: v1 kind: Service metadata: name: bluegreen spec: ports: - port: 80 protocol: TCP targetPort: 8080 selector: app: bluegreen version: v1.0 type: ClusterIP
kubectl apply -f bluegreen-service.yaml
kubectl get svc
在w1上不斷訪問觀察 while sleep 0.3;do curl cluster-ip/dockerfile;echo "";done
修改bluegreen.yaml
01-deployment-name:blue ---> green 02-image:v1.0---> v2.0 03-version:v1.0 ---> v2.0
kubectl apply -f bluegreen.yaml
kubectl get pods
同時觀察剛纔訪問的地址有沒有變化,能夠發現,兩個版本就共存了,而且以前訪問的地址沒有變化
修改bluegreen-service.yaml :
# 也就是把流量切到2.0的版本中 selector: app: bluegreen version: v2.0
kubectl apply -f bluegreen-service.yaml
kubectl get svc
同時觀察剛纔訪問的地址有沒有變化。發現流量已經徹底切到了v2.0的版本上
金絲雀部署/灰度發佈/AB測試:
修改上述 bluegreen-service.yaml
selector: app: bluegreen version: v2.0 # 把version刪除掉,只是根據bluegreen進行選擇
kubectl apply -f bluegreen-service.yaml
同時觀察剛纔訪問的地址有沒有變化,此時新舊版本可以同時被訪問到,AB測試,新功能部署少一些的實例.