哲學有各種各樣的流派,百家争鳴,但是隻有一個哲學問題是嚴肅的,那就是生與死。而雲端傳遞過程中也隻有三個問題是嚴肅的。
如何重建你的系統 how to recreate your system?
如何安全地部署你的系統 how to safely change your system?
部署後的問題監控與解決 when something has gone wrong?
在前面的文章中,我們講述了什麼是雲端傳遞,如何搭建從零搭建一個持續傳遞系統,而今天我們要談的是如何安全的部署你的系統,部署這個名詞包含了很多的含義,最簡單的解釋就是如何讓你的程式運作在最終的環境上。但是部署的方式上面有非常多的最佳實踐。接下來我們來讨論下常見的幾種釋出方式,以及如何利用容器釋出實作最常用的零當機釋出方式藍綠釋出。
常見的釋出政策有藍綠釋出、金絲雀釋出(灰階釋出)、abtest,在國内的開發者中,對這幾個概念有獨立的了解。藍綠釋出通常被大家成為熱部署;金絲雀釋出在國内的名頭完全被他的變種釋出方式蓋過了,主要是灰階釋出與abttest,下面我們來詳細的為大家解釋一下他們之間的異同。
在釋出的過程中使用者無感覺服務的重新開機,通常情況下是通過新舊版本并存的方式實作,也就是說在釋出的流程中,新的版本和舊的版本是互相熱備的,通過切換路由權重的方式(非0即100)實作不同的應用的上線或者下線。
金絲雀釋出
通過線上上運作的服務中,新加入少量的新版本的服務,然後從這少量的新版本中快速獲得回報,根據回報決定最後的傳遞形态。
灰階釋出是通過切換線上并存版本之間的路由權重,逐漸從一個版本切換為另一個版本的過程。雖然馬丁·扶老耳朵大人認為灰階釋出與金絲雀釋出是等同的,但是在具體的操作和目的上面個還是有些許差别的。金絲雀釋出更傾向于擷取快速的回報,而灰階釋出更傾向于從一個版本到另一個版本平穩的切換。
abtest和灰階釋出非常像,但是從釋出的目的上,可以簡單的區分灰階釋出與abtest,abtest側重的是從a版本或者b版本之間的差異,并根據這個結果進行決策。最終選擇一個版本進行部署。是以和灰階釋出相比,abtest更傾向于去決策,和金絲雀釋出相比,abtest在權重和流量的切換上更靈活。
下面我們通過一個簡單的例子來示範藍綠釋出的流程。假設我們要進行藍綠釋出的應用是一個nginx的靜态頁面,初始的應用模闆如下
部署後會有“welcome to nginx”的成功頁面提示。如果使用者想變更配置, 可以在操作面闆上選擇“變更配置”,進入資訊修改階段,選擇變更的釋出政策與新版本服務的配置。
在藍綠釋出中,新版本與舊版本不能共用同一個名字;如果共享同一個路由位址,那麼需要添加aliyun.routing.coexist的label,這個label的含義是,目前的服務與其他服務共享路由位址,在藍綠釋出的場景中,為了保證應用的零當機切換,新版本的服務的路由權重預設為0,需要通過路由管理頁面進行調整,方可進行流量切換。
在進行釋出的過程中,會經曆兩個狀态,一個是藍綠釋出中,一個是藍綠釋出待确認。“藍綠釋出中”表示,新版本的服務尚未啟動完成;而“藍綠釋出待确認”表示新版本的服務已經啟動完成,此時需要進行釋出确認或者釋出復原方可進行下一次釋出。其中,新版本的應用和舊版本的應用并存,前者用綠色标明,後者用藍色标明。如果一個服務在前後兩個版本中都存在且沒有變化,那麼會使用黃色标記,表示這個應用在藍綠釋出中不會出現任何變化。
選擇“路由清單”之後再點選“設定服務權重”,調整與之對應的路由權重。如圖所示,舊版本服務的權重為100,新版本服務的權重為0;下面我們将舊版本服務的權重調整為0,新版本服務的權重調整為100。
由于預設路由服務是進行會話保持的,您可以打開一個新的浏覽器視窗,通路新的版本,結果如下。
當整個釋出流程驗證完畢後,需要進行釋出确認,方可進行下一次釋出。
點選釋出确認後,檢視應用的詳情,可以看到應用的服務清單已經更新了,舊的服務已經完全下線删除了。
大于大多數場景而言,對客戶提供服務的軟體的形态有三種。一種是前端類服務,使用者可以直接或者間接通過網頁、接口調用使用該服務提供的能力;一種是後端類服務,使用者無法直接使用該服務提供的功能,該服務主要的使用者是其他服務,并通過其他服務最終将處理後的結果回報給使用者;第三種是排程任務類服務,即不被使用者使用也不被其他服務調用,它的生命周期隻存在在一個任務的執行生命周期中,通常任務的執行周期完畢,服務的生命周期就停止,通常為無狀态資源密集性服務。
對于上述三種場景,以路由權重切換為主要實作方式的釋出政策例如藍綠釋出、a/btest等通常情況下比較适用于前端類服務與後端類服務。下面我們用一個簡單的例子來拆解下如何使用阿裡雲容器服務來實作這兩類服務的藍綠釋出。
在上一篇釋出政策的文章中,有的開發者會問我的應用的拓撲關系不是單體的,不能通過單一容器級别的路由權重切換解決。在此要明确的一件事情,藍綠釋出是一種釋出政策,部署的最小次元是容器,而釋出的最小次元是應用。藍綠釋出的原理是老的應用的版本不變,新的應用版本進行部署,如果新版本與老版本之間應用的名字以及相關的配置沒有改變,那麼會認為這個應用是新老版本中共用的,無需變更;需要進行變更的應用通過名字的不同進行區分。簡單的來講,藍綠釋出是一個應用級别的更新操作,你可以對一個服務進行兩個版本之間的切換,服務是一個邏輯的概念,而不是容器這樣一個實體的概念,藍綠釋出可以做複雜拓撲的應用更新操作。
下面我們通過一個拓撲結構複雜一點的例子來講述藍綠釋出。應用的拓撲結構如下:
serviceb會調用servicea,這兩個都是python建構的,代碼如下:
servicea通過接口傳回資料“world!”
serviceb調用servicea的接口,并将傳回的資料字段前面添加“hello ”
傳統應用之間的調用方式可以是通過配置ip位址或者域名來調用,也可以通過服務注冊中心中的位址的方式調用,但是對于一個無狀态的多執行個體的服務,常見的做法是使用用戶端的負載均衡器或者伺服器的服務均衡器端點來實作。在容器服務中使用的方式是使用伺服器端的負載均衡端點的方式,提供内部調用的路由端點,來實作後端服務的負載均衡。大緻的調用方式如下。
serviceb通過external_links的方式将servicea的内部路由端點引入,在環境變量中将
通路serviceb的對外通路位址,可以得到:
我們最開始基本結構的應用就已經部署完畢了,下面開始進行不同服務的藍綠釋出。
首先我們先看如果做前端服務的藍綠釋出,也就是說要對serviceb進行藍綠釋出的流程。大緻的結構圖如下。
在這個應用中前端服務的藍綠釋出,也就是對serviceb進行藍綠釋出,下面我們修改serviceb的代碼
修改編排模闆,進行藍綠釋出
進行藍綠釋出更新後,可以看到更新後的服務清單,其中黃色的servicea-v1表示目前的應用在藍綠釋出的過程中不會産生變化,serviceb-v1為老版本,serviceb-v2為新版本
通過路由清單選擇相應的權重管理,進行權重的調整,将servicea-v1的權重調整為0,将servicea-v2的權重調整為100,此時通路serviceb的網址可以發現。
驗證完畢,點選确認釋出完成,完成藍綠釋出。
我們再看下如何做後端服務的藍綠釋出,也就是說對servicea進行藍綠釋出。大緻的結構圖如下。
修改編排模闆
部署後的服務清單:
此時可以發現serviceb-v2在本次釋出中不會進行變更,調整服務的權重
此時再通路serviceb的位址,可以得到如下的結果
藍綠釋出是一種用于更新與更新的釋出政策,對于增量更新有比較好的支援,但是對于涉及資料表結構變更等等不可逆轉的更新,并不完全合适用藍綠釋出來實作,需要結合一些業務的邏輯以及資料遷移與復原的政策才可以完全滿足需求,希望給位開發者可以在自己的業務場景中,更靈活的使用和實作藍綠釋出。
<a href="https://github.com/ringtail/bluegreendevelopment"></a>