通常若一有新版本服務要上線時,都需要考量到移轉到新的服務是否會對舊有的服務造成衝擊?
例如下面這張圖,目前k8s上運行著一個 nginx 1.14.2-alpine版本,現在打算想要更新nginx版本
一般來說會有以下2種做法
- 將所有存在的Pods都砍掉,再換成新的Pods
- 可能會有一些down-time的狀況發生
- 先將新的Pods運行起來,然後再砍掉Pods
- 新舊版本都會存在,同一時間會非常吃CPU與Memory的使用量
可以看到第1種策略勢必會影響到客戶的使用體驗,因為得中斷服務使用。
第2種策略在資源不足的情況下,更容易造成服務的不穩定。
這時候透過k8s本身提供的升版佈署的機制,可以避免上述的副作用。若新版的服務若有問題,k8s也提供了回滾機制,可以快速恢復為原本服務。
k8s 佈署的方法
以這張圖來看,負責進行升版與回滾的機制的元件為 “Deployment” 與 “Replicaset” 這兩個元件所組成
k8s提供了三種作法,可以實現 “zero-downtime” 佈署的方法
- Rolling Updates
- Blue-Green Deployments
- Canary Deployments
1. Rolling Updates 滾動更新
在k8s中,透過取代Pods的方式,並且不會影響到客戶端使用服務(Pods)的流量!
這種做法就叫做 Rolling Update
作法&參數解析
k8s預設的策略就是RollingUpdate,可以在 spec/strategy
中設定
其各個參數說明如下:
1 | apiVersion: apps/v1 |
-
註1: maxSurge: 在執行RollingUpdate過程中,最大的可超過replicas數值的Pod數量
- 若maxSurge設置為1, 表示除了replicas設置的2個pods數量,還可以再多一個
- 例如 2個 新版的pods, 1個舊版的pod
-
註2: maxUnavailable: 在執行RollingUpdate過程中,沒有在運作的Pods數量
- 若設置為maxUnavailable 1, replicas設置為2, 表示只會有一個pod在rolling update過程中停機。
相關指令
-
kubectl create -f [yaml file] --save-config --record
--save-config
: 將configuration儲存到resource’s annotation--record
: 將部署的command儲存在Deployment revision history內
-
kubectl apply -f [yaml name] --record
--record
: 將部署的command儲存在Deployment revision history內
-
kubectl rollout status deployment [deployment-name] --revision=2
: 取得deployment rollout的狀態--revision
: 只會給指定的revision資訊
-
kubectl rollout history deployment [deployment-name]
: 取得執行rollout的歷史紀錄 -
kubectl rollout undo [yaml file] --to-revision=2
: rollback到指定的yaml檔案設定檔,或是指定的執行歷史--to-revision
: 回滾到之前曾執行過的rollout狀態
範例:Rolling Update範例:使用RollingUpdate策略部署 nginx
請至 Rolling Update範例:使用RollingUpdate策略部署 nginx
一節查看
議題:若Pods提供的是前端網頁服務,在Rolling Updates時會發生頁面中斷的情況
由於k8s Services層機制實現負載平衡的效果,使得我們很難事先曉得Client會使用的是哪一個Pods,故這時Rolling Update在此情況下無法解決此議題。
2. Canary Deployments 金絲雀部署
Canary Deployment的中文翻譯為 金絲雀部署
,因為以前在礦工進入洞穴時,會先透過金絲雀進入洞穴,以便探路,就像軟體部署,也要有先測試的版本先出來。
Canary Deployment主要目的是先切割目前使用者為 大族群與小族群,
部署新版的給小族群測試使用,稱作 Canary
版本,然而大族群的客戶一樣使用舊版本。
- 同時運行兩個Production環境
- Canary版本獨立運作,不干擾原本的服務
- Canary版本會被分配到較小的流量
配上K8S服務的概觀大概如下圖所示
作法&參數解析
基本上進行canary部署,只需要改動deployment設定檔中的replicas數量與container服務就好,並配置適當的 service服務做負載平衡
範例:使用Canary佈署策略, 以Web App為例
請至 範例:使用Canary佈署策略, 以Web App為例
一節查看
3. Blue-Gree Deployments 藍綠部署
藍綠佈署是一個釋出軟體程式碼的變動策略,保證系統再不中斷時,能提供服務的部署方式。
藍色通常代表舊的運行服務,綠色代表新的運行服務
需要有相同的硬體設備,以及相同的設定
作法&參數解析
將標注藍色的服務保持正常運作,持續提供給用戶,另外一個綠色的服務則是佈署完新版本的服務,待測試完畢後進行待命
Step 1. 藍綠部署流程第一步會先建立藍色代號的Pod與Service,並與既有運作系統的Service導入到相同的Pods
此階段會有著
- Blue Service 設定檔
- Public Service 設定檔
- Deployment 設定檔
通常會在Public
與 Blue Test
的Service yaml檔案內的labels
-> role
標註為 blue
Blue Test Serivce
1 | kind: Service |
Public Service
1 | kind: Service |
Deployment設定檔
1 | apiVersion: apps/v1 |
Step 2: 接著再部署綠色代號 (新版本) 的Pod與Service,並給QA做測試
這時可看到與canary deployment的差異,blue-green deployment不會讓使用者同時呼叫到舊版本與新版的服務
Green Deployment設定檔
1 | apiVersion: apps/v1 |
Step 3: 轉移到綠色服務
若QA team測試完綠色代號的新版本服務,就可以將 Public Test Service的流量從舊版本的服務 Blue
切換到新版的Green
服務了
透過更改Public Serivce內的selector為 green
,就可以將流量導到labels標註為green
新版本的Pods了
Public Service
1 | kind: Service |
相關指令
-
kubectl apply -f [yaml]
: 套用更動後的設定檔 -
kubectl set selector svc [service-name] 'role=green'
: 將service內的role更改為green
範例:使用Blue-Green佈署策略, 以Web App為例
請至 使用Blue-Green佈署策略, 以Web App為例
一節查看
參考
Pluralsight: Kubernetes for Developers: Deploying Your Code
https://app.pluralsight.com/library/courses/kubernetes-developers-deploying-code/table-of-contents