天天看點

莫源:像搭積木一樣玩轉Docker的持續傳遞

雲栖techday活動第十八期中,阿裡雲的進階研發工程師莫源帶來了題為《像搭積木一樣玩轉docker的持續傳遞》的分享,主要講解了阿裡雲容器服務實作基于docker的持續傳遞、容器持續傳遞的設計思路和未來發展反向。

以下為現場分享觀點整理。

最近docker越來越火,持續傳遞的概念也随着被大家越炒越火。對于持續傳遞而言,1000個人有1000種了解,關于持續傳遞的演講内容即打通小異又大相徑庭。大同小異是指大家對持續傳遞的基本了解是相似的,但對持續傳遞的實作方式是大相徑庭的,這是為什麼呢?

這是因為持續傳遞其實是一個概念,它并不是一個具體實作的方式,而是說按照持續傳遞的指導思想和規範來實作自己的持續傳遞系統。

<b>用lego的思維看基于docker的傳遞方式</b><b></b>

莫源:像搭積木一樣玩轉Docker的持續傳遞

傳遞方式一直在不斷地演進、不斷地變更,如上圖所示,一個較大的公司内會有多個技術站、多個不同應用。不同應用有着各自不同的開發環境和運作環境,所對應的傳遞場景也更不相同。是以,當公司體量越來越大、業務越來越豐富時,你就會發現傳遞場景也會變得越來越豐富,帶來的挑戰也越來越大。

莫源:像搭積木一樣玩轉Docker的持續傳遞

常見的傳遞流程主要包括三要素:開發、測試、運維。開發人員開發代碼并在本地或測試環境測試,通過後将其送出給測試人員;測試人員在測試環境中利用手工測試或自動化測試,将整個流程驗證開通,如果不存在問題,則應用即可上線;最後一個步驟是運維人員将相應的代碼部署到機器上,然後對後期應用做運維,例如可能會初始化一些腳本、軟體環境,做一些後期日志的收集、監控、告警以及系統的調優。

<b>這幾個步驟運作流暢實際上有幾個基本前提:</b>

第一個前提是要有一套基礎的技術棧和環境自動化流程,才能實作應用的快遞傳遞;

第二個前提是團隊的技術架構盡可能保持穩定;

第三個前提是需要具有良好的文檔和技術沉澱,文檔中應該寫清楚如何運維、部署、調試以及問題的解決方法,同時相同問題出現第二次時,應該可以憑借技術沉澱立即修複;

第四個前提是團隊成員相對穩定,當團隊人員經常發生變化時,盡管有之前的文檔等等資料,但還需要一個熟悉過程,不免會導緻效率的降低。

莫源:像搭積木一樣玩轉Docker的持續傳遞

這些問題在公司都是非常常見的現象,尋根究底時,其實主要是由三個問題導緻的:

第一,傳遞流程不能良好的自動化或自動化成本過高,如果部署應用可以變成一個按鈕,屏蔽技術障礙,則可以輕松實作應用的傳遞。

第二,傳遞缺乏自描述的機制,嚴重依賴文檔或口傳心授。

第三,不同角色對于職責的交叉地帶缺乏合作,例如開發、測試、運維同學之間,最重要的事是将軟體傳遞出去,但是子啊職責的細分過程中,很多交叉領域是沒有一個明确地劃分的,導緻有的地方是誰有責任心誰做,職不明,進而導緻缺乏合作。

<b>三個問題總結成三個詞就是:自動內建難、持續傳遞難、合作協同難。</b>

莫源:像搭積木一樣玩轉Docker的持續傳遞

很多人都在安利docker為傳遞而生,是一種輕量級的作業系統虛拟化方案。使用docker時,虛拟機還可以使用之前的hypervisor,依舊可以使用vm的方式進行部署;上方應用可以利用docker技術部署,實作彈性應用架構,還可以完美地實作隔離。

這些看上去都很美好,但到底如何解釋它和傳遞之間的關系呢?

莫源:像搭積木一樣玩轉Docker的持續傳遞

在樂高積木中,有件非常偉大的事情,就是标準化模組,各個小子產品之間有互相的接口,最終可以完成不同形狀的拼接。docker同樣做了一件偉大的事情:标準化傳遞,也就是所謂的軟體定義傳遞。将複雜的php環境、java環境轉變為标準的dockerfile,不同的環境可以同樣的方式打包,标準haunted了軟體環境。

在docker中,docker的命名不用關心容器内是php應用還是java應用,也就是說不同種類的應用可以用相同的指令或api管理,規避了不同軟體之間的差别,标準化了軟體形态。

不同應用之間是具有互相調用關系的,之前,是在配置檔案内加以說明;現在,可以将這件事情一到docker場景之下,利用編排模闆解決該問題。在編排模闆中,可以申明不同應用之間的互相調用關系、部署形态以及節點的數目和分布政策,也就是不同應用拓撲關系變成了遵循特定文法的編排模闆,編排模闆可自描述,編排模闆确定時,應用形态也随之确定,标準化了傳遞流程。

<b>持續傳遞+docker=containerops</b><b></b>

莫源:像搭積木一樣玩轉Docker的持續傳遞

雖然這裡寫到持續傳遞+docker=containerops,其實持續傳遞更像是一個哲學問題,不同的人會有不同的答案,因為持續傳遞是和場景密切相關的。我們所要做的是:不要将持續傳遞當成一個固定的流程,真正的持續傳遞是和業務密不可分的,符合你自己的業務場景的持續傳遞才是最好的持續傳遞。

莫源:像搭積木一樣玩轉Docker的持續傳遞

在持續傳遞中,真正嚴肅的問題隻有三個,分别是:如何重建系統?如何安全地部署系統?部署後的問題監控與解決?逐個問題進行翻譯,重建系統的意思是部署一個軟體之後,如何初始化環境,如何将對應的技術站做好;如何部署系統是說,軟體代碼已經準備好了,環境也已經搭建好了,如何進行釋出;第三個問題是隻軟體釋出部署後,在運作時所遇到的各類問題,如何去做警告如何去監控、復原等。将這個三個問題解決好,屬于你自己的支付系統就搭建完畢了。

莫源:像搭積木一樣玩轉Docker的持續傳遞

首先來看一下如何重建系統,即如何初始化環境。正如上文提到,最終軟體環境都會變成dockerfile,dockerfile中具備了全部的軟體基礎環境,如烏班圖;同時也具備軟體運作環境,如java和php;此外,還包括軟體運作的代碼和軟體運作的指令,最終所有的軟體環境都會變成dockerfile定義的鏡像,該鏡像可以運作應用、重建系統,解決初始化環境的問題。

軟體釋出時,不同的軟體之間是有互相依賴的,互相關聯的軟體可以通過編排模闆标準化部署,本地可以運作遠端便可以傳遞。

對于運維時的監控、告警、復原等操作,大部分情況是由上層的容器服務商來提供的,通過調用docker标準的api擷取容器狀态,出現問題可以通過鏡像復原、更新、擴容。

<b>阿裡雲容器服務持續內建模組</b><b></b>

下面來看一下阿裡雲是如何實習持續傳遞系統的,阿裡雲提供的是把我們底層的雲資源整合起來的一個能力。

莫源:像搭積木一樣玩轉Docker的持續傳遞

上圖展示的是阿裡雲容器服務和周邊的生态,圖中左邊和右邊都是阿裡雲的iaas層服務,如雲資料庫、緩存服務等,如果想在容器内使用資料庫,是可以使用阿裡雲提供的雲資料庫去做;如果想用消息隊列,也可以找到對應的雲産品。

中間部分是阿裡雲容器服務提供的模組部分,阿裡雲容器服務和其他容器服務提供商不同,大多數容器服務商更傾向于采用pass去做這個場景,阿裡雲更側重是将使用者的能力進行整合,然後提供給使用者更多的雲資源。阿裡雲容器服務采用docker swarm編排系統,進行上層管理,完全相容docker社群;同時阿裡雲容器服務在docker上進行了容器編排、彈性伸縮、叢集管理;此外,在服務級别做了discover service,即服務的注冊和發現,進行同步和異步通信,諸如不間斷釋出也是來源釋出這一部分。再上一層支援兩種路由:一是vm級的路由;另一種是阿裡雲内部的自定義的路由服務。

<b>容器hub持續傳遞模組</b><b></b>

莫源:像搭積木一樣玩轉Docker的持續傳遞

來講一個很簡單的傳遞案例:代碼變更後,遠端線上也随之更新的簡單案例。這裡主要運用了容器hub的持續傳遞模組,該模組由三部分組成:容器hub、代碼倉庫、容器服務觸發器。運用這三個模組之後就可以實作本地送出代碼,遠端自動更新。

莫源:像搭積木一樣玩轉Docker的持續傳遞

原理如下:開發者在本地送出代碼之後,會将代碼送出到代碼倉庫,目前容器hub內建的代碼倉庫有阿裡雲code、github和bitbucket;當源代碼倉庫發現開發者所送出的代碼後,将該消息通知給阿裡雲容器hub,容器hub确定送出代碼的分支,會根據該分支對應的代碼branch,将代碼下拉,然後進行鏡像的自動化建構;鏡像自動化建構完成後會通過一個觸發器的方式觸發容器服務進行應用的自動部署;容器被觸發後,下拉最新的鏡像,重新運作應用。通過這個流程來實作最簡單的傳遞系統。

<b>jenkins持續傳遞模組</b><b></b>

莫源:像搭積木一樣玩轉Docker的持續傳遞

下面來講一個更複雜點的持續傳遞方式,是一種開源方案:jenkins持續傳遞模組。該模組主要分為代碼倉庫、jenkins master、jenkins slaves、容器hub、容器服務觸發器或jenkins部署插件五部分。

莫源:像搭積木一樣玩轉Docker的持續傳遞

整個傳遞的大緻流程如上圖所示。jenkins實際上是開源中常見的持續內建所用的center,大家可能會把它作為持續內建或持續傳遞的server。jenkins實際上是開源的持續內建server中功能最為強大,生态最為豐富的,包含各類所需的插件,如支援靜态代碼掃描的soma插件等等。

jenkins内部的次元是一個job次元,例如你想做一次持續內建,則相當于該job執行之後便可以做完持續內建,但這個job的運作并不是在jenkins本機上運作的。jenkins是主從結構,它是master/slave模式(在容器服務中,推薦使用該模式),在該模式下,一個job會從jenkins master分發給jenkins slave,而在jenkins slave上完成job的具體任務。

對于上述案例,開發者首先将代碼送出到源代碼管理倉庫;該代碼倉庫會通知jenkins master,jenkins master會将相應的任務分發給對應的jenkins slave;在jenkins slave内,使用者可自定義流程、建構方式,同時在jenkins slave内,完成代碼的編譯和測試、代碼的image build and publish,以及最終部署的觸發器。

莫源:像搭積木一樣玩轉Docker的持續傳遞

在jenkins slave内可以完成很多事情,這裡隻是采用預設時限,來幫助大家簡化開發。在slave内,我們定義了四個流程,分别是:build、test、image build and publish和probe trigger。

這裡以java應用舉例,build流程類似于maven build功能,會打包成一個jar包或war包、tar包。test流程是完成測試功能,可以完成單元測試、內建測試,也可以融合二者同時運作,不同的測試類型取決于對應的業務形态。image build and publish流程相當于将build之後的結果根據dockerfile建構成所需的鏡像,再将該鏡像推送到hub倉庫中。第四個步驟實際上是觸發自動重新部署,或者使用插件重新部署。

莫源:像搭積木一樣玩轉Docker的持續傳遞

在上述流程内,遇到了各種各樣的問題,這裡與大家進行一一分享。

<b>首先第一個問題是:</b>jenkins官網的鏡像大多跑不起來。經過排查後,發現問題出現在鏡像内部,因為jenkins預設執行的權限為jenkins的user,挂載的jenkins_home寫權限不足。在阿裡雲容器服務中提供了自己的jenkins鏡像,在該鏡像中采用先提權後解權的方式,實作了主控端挂靠鏡像運作權限的問題。此外,阿裡雲容器服務還打包了一些常見的開發插件,幫助大家減少下載下傳插件的時間和下載下傳失敗的可能性。

<b>第二個問題是:</b>jenkins slave中建構鏡像,怎麼處理docker in docker。針對該問題,可以将/var/run/docker.sock傳遞進入slave,這樣slave中的docker相當于一個client,而真正的engine是主控端的docker,會使用主控端的資源。

<b>最後一個問題是:</b>jenkins持續傳遞中多套環境如何解決。最簡單的方式是采用git workflow的方式,實作不同分支不同權限、開發環境、預發環境自動釋出,不同特定分支釋出到特定的環境,線上分支采用手動釋出,可以使用多種釋出政策實作0當機釋出。

<b>藍綠釋出模組</b><b></b>

莫源:像搭積木一樣玩轉Docker的持續傳遞

藍綠釋出是指應用版本進行藍綠釋出時,在其他幾台機器上或環境中起一套類似的版本(新版本),兩個版本之間共享一套路由;通過路由權重的切換方式來實作不同版本之間的切換。例如,先上線a版本,然後又上線了b版本,如果想檢視b版本是否正常,可以吧線上路由從a切換到b,驗證沒問題時,進行confirm,confirm動作會吧原來的老應用删掉,新應用完全上線;如果應用b存在問題,則把路由切換到a,再進行復原操作,将新釋出的應用下線掉。

莫源:像搭積木一樣玩轉Docker的持續傳遞

藍綠釋出是基于路由來實作的,是以要涉及容器服務裡邊網絡狀況。上圖是容器服務的網絡示意圖。在容器服務中共支援四種網絡模型:none,即無網絡,相當于容器裡隻有ip,對外無法通路;第二種是bridge模式,bridge模式相當于把容器裡邊的端口映射到主控端上的端口;第三模式是host模式,host模式就相當于完全共享主控端的網絡;第四種模式是容器服務現在預設提供的網絡模型,叫only網絡,only網絡實際上是一種container的實作。它大緻原理是:不同虛拟機、容器之間實際上有一個大的container網絡,在這個網絡内,所有容器時互通的。但從主控端的網絡通路二層網絡還是不同,因為它們是不同的網絡模型。阿裡雲容器服務提供的路由服務,是基于ha proxy的實作,而ha proxy的實作主要完成的工作就是将兩層的網絡模型進行一次打通,使用者可以通過ha proxy來轉發到二層網絡内的任一容器。災不同容器之間進行權重切換時,權重是在ha proxy層完成的。目前對ha proxy層支援兩種路由方式:内部路由和外部路由。外部路由相當于是對外通路時用的,而内部路用于應用之間的互相調用,相當于是内部的負載均衡。

莫源:像搭積木一樣玩轉Docker的持續傳遞

對于藍綠釋出,常見的應用場景包括:利用jenkins模組進行自動內建,完成測試環境和預發環境的自動釋出。在手動釋出中,采用的是藍綠釋出0當機釋出。

藍綠釋出的大緻政策是:兩個版本并存,通過權重切換的方式來實作流量的上線和下線的切換;驗證無誤的時進行釋出确認,删除老版本容器;驗證無法通過的時候就釋出復原,這時新版本的容器就删除。