本教學已加入 Istio 系列:https://istio.whuanle.cn
專案總是處於不斷變化之中,每次釋出新的版本時,都考驗了團隊的運維能力。
新版本上線之前,經歷過開發和測試人員的驗證,也經過產品經理的驗收。可是當要上線到生產環境時,誰也保證不了上線一定就能跑起來。所以往往需要在上線時保持新版本和舊版本同時在用,測試人員或內測使用者可以存取新版本,其他人繼續使用舊版本。再有就是上線時新舊系統能夠絲滑切換,使用者完全感知不到這種變化。
並且新版本上線時,不應該影響舊版本的執行,要求實現不停止更新。但是除了應用本身,還涉及到新舊版本共有同一個資料庫,新舊版本應用對應的資料庫表結構不一樣。
新舊版本切換帶來的問題很多,但是,在本系列教學中我們只考慮外部存取效果即可。
很多專案的版本更新做得並不好。很多初級階段的 Web 服務團隊,每次更新都需要中斷當前的應用,後端服務有一段時間內不可用。如果新版本有問題,那麼還需要重新發布舊版本。如果只是內部服務,問題不大,可是如果系統是給客戶使用的,那麼很容易讓客戶給出一個低分的評價。
Kubernetes 中雖然有捲動升級,能夠逐漸使用新版本的 Pod 替換舊版本的 Pod,兩個版本共存,但是並不能做到流量自由切分,一個流量進入時,依然會在新舊版本的 Pod 中輪詢選擇。但是我們還是可以調整 v1 和 v2 的 Pod 數量,實現流量按照比例劃分,比如 v1 的 Pod 數量有 40 個,v2 的 Pod 的數量有 60 個,那麼按照比例,會有 60% 的流量進入到 v2 中。不過這樣並沒有什麼鳥用。
Kubernetes 捲動升級、伸縮參考資料:https://k8s.whuanle.cn/3.pod/6.scale.html
Istio 中雖然沒有名為 金絲雀釋出的功能,但是按照之前我們所學到的 Istio 的 VirtualService 、DestinationRule 就可以實現根據請求的 header 等,將流量轉發到不同的子版本中,我們使用這些操作方法即可實現金絲雀釋出。
尷尬,在學習 Istio 之前,我對藍綠髮布、灰度釋出、金絲雀釋出的概念並不清晰,很多文章都是將它們分成三類釋出方式。實際上藍綠髮布和金絲雀釋出都是灰度釋出的一種。
灰度釋出是兩個版本共存,將一小部分流量切到新版本中,當新版本經過一段時間驗證後,如果沒有問題,再將流量逐步切換到新版本中。
所以,可以把藍綠髮布、A/B 測試、金絲雀釋出都劃分為灰度釋出。
當然,它們有一些差別,每個人的劃分方法也有差別,有的說法是金絲雀釋出才是灰度釋出。
藍綠髮布
藍綠髮布的方式是使用另一套資源部署新版本,然後將舊版本的流量都切換到新版本中去,缺點是需要消耗兩套資源,而且藍綠髮布是全量切換,如果新版本出現問題則會影響到所有使用者。
A/B 測試
A/B 測試是同時部署兩個版本對等的版本來接收流量,但它不是指新舊版本。比如,產品經理有一個好主意,做新時代的農場區塊鏈,想知道大家喜歡養豬還是養雞。於是釋出了養豬農場和養雞農場兩個對等的應用,然後邀請不同的使用者進行內測,喜歡養豬的使用者會被導向養豬農場應用。然後收集使用者的意見和各種指標資料,分析使用者喜歡養什麼動物,最後決定上線什麼版本。
現在使用命令將 v1 版本增加到 10 個 pod。
kubectl scale deployment reviews-v1 -n bookinfo --replicas=10
在原設定不變的情況下,我們來部署 VirtualService,將流量的 90% 打入到包含 10個 Pod 的 v1 版本。因為 v2 版本只有10% 的流量,所以只需要 1 個 Pod 也可以支撐了叭。
kubectl -n bookinfo apply -f - <<EOF
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: reviews
spec:
hosts:
- reviews
http:
- route:
- destination:
host: reviews
subset: v1
weight: 90
- destination:
host: reviews
subset: v2
weight: 10
EOF
命令之前完畢之後,不斷重新整理 productpage頁面,會發現大部分情況下不會顯示評星,少部分情況會出現黑色的星星。
當然,也可以使用 header 的方式,將流量匯入到不同的版本中。比如只有測試人員的流量才會打入到新版本中。
http:
- match:
- headers:
end-user:
exact: jason
route:
- destination:
host: reviews
subset: v2
- route:
- destination:
host: reviews
subset: v1
當我們檢查 v2 版本沒有問題之後,我們就將 v2 版本擴容。
kubectl scale deployment reviews-v2 -n bookinfo --replicas=10
與此同時,修改 VirtualService,將全部流量路由到 v2 中。
kubectl -n bookinfo apply -f - <<EOF
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: reviews
spec:
hosts:
- reviews
http:
- route:
- destination:
host: reviews
subset: v1
weight: 0
- destination:
host: reviews
subset: v2
weight: 100
EOF
當一段時間後,如果一切正常,將 v1 版本的 Pod 數量降低為 0。
kubectl scale deployment reviews-v1 -n bookinfo --replicas=0
但是不要刪除 v1 版本,如果新版本出現問題,我們只需要調整 v1版本的 Pod 數量,然後修改 VirtualService ,將理論匯入到 v1 即可。
金絲雀釋出其實很簡單,除了 Istio 之外,我們通過 Nginx、Apisix、Kong 等閘道器都可以輕鬆實現。