您好,登錄后才能下訂單哦!
通聯數據是如何使用Docker+Rancher構建自動發布管道的,針對這個問題,這篇文章詳細介紹了相對應的分析和解答,希望可以幫助更多想解決這個問題的小伙伴找到更簡單易行的方法。
大家好,今天我將分享通聯數據使用Docker和Rancher構建自動化發布管道的經驗,我會介紹通聯數據自動化發布的流程及方案設計,我們從踩過的一些坑中總結出來的經驗,以及我們的自動化發布管道的系統運行現狀。
通聯數據是一家這幾年新崛起的金融科技公司,主要目標是致力于將大數據、云計算、人工智能等技術和專業投資理念相結合,打造國際一流的、具有革命性意義的金融服務平臺。這里面涉及到幾個關鍵詞:大數據、云計算、人工智能,這些熱詞已經有很多企業提及過,因此我也不贅述了。
通聯數據作為一家創業公司,也會遇到很多創業公司都會遇到的問題,比如產品太多,而且每年很多產品都會推翻重來,就會遇到各種各樣的問題。比如,應用在開發時,涉及到需要多少CPU、需要用什么語言去編程等問題,開發人員不會與后臺人員事先溝通,出來一個產品,直接讓運維人員上線。
基于這樣一個背景,我們迫切需要打通上線這條管道,因為在可預見的將來,通聯數據每年將會有大量的新應用出現,如何打通上線這條管道亟待解決。
我們做的第一件事,就是做持續集成。由于我們公司每年會有上百個新的項目產生,每個項目的語言、框架、部署方法都不盡相同,發布流程也是比較冗長低效的,部署應用占用了運維人員大量時間。
我們決定用容器解決這個問題,評估了多家供應商后選擇了Rancher,主要原因在于:
首先,Rancher的操作界面非常簡單,相信用過Rancher的人都會有這種感受,它不需要太多專業的知識,很容易上手;其次,Rancher在部署時也非常簡單,可以一鍵式部署,Rancher還提供了良好的API支持,方便集成。
隨后,我們開始搭建自己的CI/CD。當時我們在流程方面遇到了很多困境,下圖已經是簡化制作后的了,實際上還有更多各種各樣的分杈和分枝:
就我們原來的流程來說,流程最開始的部分是研發;隨后進入QA環境部署,這時候就需要人去部署,通常是運維人員,但是運維一般不愿意做這個事情;部署完成后,進入QA環境測試階段,通知開發和測試人員進行測試,過程中可能會出現延遲,因為測試人員可能正忙于其它的事情,不能馬上進行測試;QA環境測試通過后,進入STG環境部署;隨后再進行STG環境測試,這幾個過程可能會循環很多次。跟著進入安全測試階段;測試通過后,還有一個正式包的一個準備過程,最后才能上生產部署。即使是這個簡化后的流程也是非常復雜的,而且其中涉及到很多線下的溝通,效率不可能高得起來。
在使用Rancher之后,原本的流程大大簡化了,改進后的簡化流程如下圖:
流程的第一步即持續集成,意味著開發人員寫好代碼后可以直接通過CI,CI觸發自動編譯,隨后自動部署腳本,測試環境已經就緒。簡單來說,每次開發人員提交代碼之后,測試環境就始終處一個就緒的狀態,這時候就可以直接進入測試階段,整個過程都處于線下,不需要走任何流程,全部實現自動化了。
測試人員完成測試后,再進行STG環境測試,因為后臺已經跟Rancher完成對接并實現自動化,這賦予了QA環境測試從未有過的強大的自動化能力,意味著QA環境測試可以自動對接到STG環境測試。測試通過后,進入安全測試階段,這個階段是公司要求的,無法避免,安全測試通過后就進入到生產部署。以前繞不開的線下溝通那些步驟和一些部署就可以省去了,整個流程優化并且簡潔,效率也提升了。
CI/CD說起來可能很簡單,比如PUSH代碼、QA環境自動就緒。但是實際操作起來并非如此,仍然存在很多需要解決的問題。比如開發的分支模型就涉及到在開發代碼的時,要PUSH什么分支才能部署,還是PUSH所有的分支都能部署?
當時我們想到最好就是PUSH任意分支都能部署,這樣就非常方便。但隨后就發現這方法行不通,會造成混亂,而且難以管理。此前我們Git的一個The Successful Branch Modeling分支模型就類似于此,此模型規定了一個develop分支、一個feature類型的分支、一個release類型的分支、一個hotfixes類型的分支和一個master分支。
在平時開發時,開發人員常常會在develop分支上切出一個feature的分支,比如,開發一個包含很多功能的story,那么所有人切一個story,這邊story有自己的ID,然后再去開發,把story開發完之后,再把它merge過來。最終,我們只選擇了一條線做CI,當代碼PUSH或者合并到develop分支時,我們幫你去做這個,而在這個feature分支的時候,我們另作處理。
feature分支意味著當用戶提交一個feature分支之后,我們會另外幫你部署一套,每一個feature分支部署一套,相當于每一個story都可以分開獨立去測試,最后把它合并到develop分支。那么測試的時候,測試可以根據自己的需求來決定它到底在哪一條分支線上去測試。
比如,A測試中如果用戶只關心story A,那就在story A這個分支測試環境去測,這些story全部合并進來之后,再進行一次集中測試,測試通過后,在發布時把這個分支切到release 的一個分支上來,然后,在release上發布正式包,讓QA在STG環境繼續進行測試,就如前面看的那個流程圖。分支模型非常混亂,為了做CI,我們會跟開發人員定義好每一條分支,每個分支對應的每個不同行為也定義好,這在混亂的分支模型下非常有用。
為了做CI,版本號的規則必須一致,如果每個團隊版本號命名不一樣的話,匹配規則就會非常麻煩和混亂。后來,我們選擇了Semantic Versioning的一個版本號的規則,就是幾點幾點X,這是一種常見的版本號命名方法,此版本號包含標準的一個文檔,文檔描述了此版本號的具體定義,第一個叫MAJOR,第二個叫MINOR,第三個叫PATCH,后面還可以加各種自己的版本號。
下面我將介紹我們的CI的觸發路徑——Git push,push到develop分支,Git push就會push到Gitlab的server上,隨后通過webhook去調用Jenkins,Jenkins會把這個包bulid出來。原本我們是想通過Jenkins調用Rancher的API,后來發現直接調用Rancher有差距,過程進行的也不那么順利,為了解決Jenkins和Rancher之間的gap這一問題,我們在它們之間裝了一個Ponyes的軟件。
為什么需要Ponyes這一中間層?它到底提供了哪些價值?
(1)動態修改版本號
首先,它可以解決動態修改版本號的問題,大家用Rancher的時候,發現Rancher的商店非常好用,我們可以在商店里把一些東西定義好,接著QA只要填幾個參數,就可以把一個應用部署起來了,沒有Ponyes這一中間層之前,必須找運維人員去做,過程也比較復雜。
為了用起來Rancher應用商店,我們還定義了一個應用商店的模板,這樣我們就可以在每次PUSH代碼的時候,把這個模板生成一個真正可以部署的應用。但是,版本號還是存在一些問題,我們每次PUSH代碼的時候,到Jenkins,我們會根據閱覽數給Jenkins升級一次版本號,比如說1.0.1.0-1,第一次閱覽是-1,第二次閱覽即-2,Jenkins的版本號根據閱覽次數相應變化。這時候應用商店也要隨之而變。
因此,我們做了這樣一個模板,通過這樣一種方式,在Ponyes中,每個Jenkins可以獲得對應的版本號,然后把這個版本號通過變量把它注入進去:
sample: image: {{ REGISTRY }}/automation/auto-sample:{{ m['auto-sample']}}
這一過程還涉及到registry,因為QA環境和STG環境是完全分開的,在進行模板渲染時,我們需要知道到底是發到QA環境還是STG環境,從而對registry的地址做出相應改變,這樣的話,上面說的修改版本號的問題就解決了。
(2)多service管理
還有一個比較棘手的問題,即一個stack中有多個服務怎么辦?比如,一個比較小的團隊可能總共就幾個人,每個人負責好幾個項目,與微服務的關系有些相似,那么一個stack可能有好幾個服務,最典型的就是前端、后端,或者是其他的一些中間件,每一項是一個服務。
開始部署時,Rancher里面的這些服務也要用一個stack來管理,有多個服務就會面臨怎樣管理的問題。比如,一個stack有ABC三個服務,服務C更新時,整個stack也應該更新版本號,因為在Rancher里面,stack被部署出來之后,有個update available的黃色按鈕,如果有新版本,點這個按鈕,就可以升級這個stack,而且必須升級整個stack,而不是只升級某個服務,這時候就需要管理多個服務。Ponyes記錄了服務和stack之間的關系,任意一個服務更新,也會觸發stack的更新,更新的方法就是每個服務每次更新,stack的版本號+1。
(3)多版本并行發布
接下來還有一個更嚴重的問題,如果多版本并行發布,我們應該怎么去處理?比如說我們ABC三個模塊,A發布過1.0和2.0,B發布過3.0、4.0,C發布過5.0和6.0。如果發布一個C應用的5.0.2,那么對應的AB模塊號應該選什么,這個問題困擾了我們很久。
有好幾種方法可以解決,比如用某個東西記錄C5.0和AB的一個版本號之間的關系,這表示用戶可以自定義。但也存在一個問題,用戶需要自己去管理它們之間的版本號關系,時間長了,可能會弄亂或弄錯版本號,或者弄錯版本號之間的關系,隨后上線到生產環境,后果更嚴重。
還有一種方法,就是將用戶的C版本號最后一次發布到5.0時AB是什么版本靜態地記錄下來。但這樣的話系統會變得相當復雜,很容易出錯。
最后,我們選擇去除多版本并行發布的能力,只支持單個版本的發布,意味著如果要發布,必須是最新版本,歷史版本可以用另外的方法進行人工處理,這樣的話,系統會更簡單,而且不容易出錯,也不需要用戶去維護一個版本號之間的關系。以上這些功能都是借助我們自己寫的Ponyes解決的。
Rancher 2.0也提到了CI/CD這樣一個功能,在實際過程中,會遇到一個非常現實的問題,從代碼研發到整個生產環境部署有許多環節,具體情況也非常復雜,而CI的作用可能僅止于QA,后面的環節還會有新的難題,這時就需要一個體系把整個生命周期貫穿起來管理,Rancher承擔的作用就在于此。
(1)部署幾套Rancher環境?
這問題看似很小,最初也在我們內部也引發過不少討論。最初我們只部署了一套Rancher,在Rancher里面用環境去區分QA或production。部署一套Rancher的方式最簡單,但是有一個嚴重的問題:Rancher升級了怎么辦?這套Rancher既管了QA,又管了production,升級的時候需要把生產環境也升級,此刻如果出現bug,問題將非常嚴重。
后來我們把它拆成四套,Rancher平臺本身也得有一個升級的環境。建議大家在前期部署Rancher的時候要部署多套環境(至少兩套),我們實際上是dev、QA、staging、production每個環境都有一套,總共四套。
(2)配置項爆炸
第二個問題是關于配置項。我們最開始是使用Rancher compose的,它非常簡單強大,我們在Rancher Catalog里點一下“部署”,配置選項全彈出來,我們只需要點選一些東西,就可以部署一個很復雜的應用。后來我們卻發現,應用的配置項越來越多(甚至多達上百個)。這導致它們難以在一個頁面里展現,同時上百項的配置讓我們無從填寫,運維也無法成功部署,我們從而面臨了配置項爆炸的問題。
我們的解決經驗是,在容器平臺里面,配置項一定要集中管理。我們把配置項全部用consul管理,每次容器啟動時到consul里把配置拉到對應的容器里來。如此一來,容器可以在任意平臺漂移。另外配置項本身在原server存有副本,我們copy原配置項加以修改,就可以部署另一個實例了。所以說,配置項一定要全部集中管理起來。
(3)泛域名+Rancher LB
我們每一個業務都有一個web服務,要申請自己的域名。每年我們有上百個項目上線,這意味著有上百個域名要申請。加上這些域名都分別需要在開發、測試、生產環境中使用,所以我們每年要申請將近五百個域名。這是一件恐怖的事情。
后來我們就用了泛域名的方法。比如用*.sub.example.com的域名,直接CNM到Rancher環境中的其中一臺主機。然后在Rancher上設置它的LB,LB就可以分布在所有的主機上,每個主機上都會有同樣的LB。這個域名任意指向一臺主機,它都可以工作。
比如說,在QA環境,這個LB上serve了如下這些域名,若主機壞掉了,容器本身會啟動,入口問題則可以很簡單地通過修改*量來搞定。如果是生產環境則可以在上面再加層nginx,配三個upstream,死掉任意一臺,還可以通過另外兩個入口進來。
使用泛域名的方法,在配置好泛域名之后,在Rancher LB上再加任意域名都不用再去申請新的域名,而是可以直接寫123.sub.example.com,然后直接在LB上配置,配完之后域名即可用,無須再走申請的流程了。
關于通聯數據是如何使用Docker+Rancher構建自動發布管道的問題的解答就分享到這里了,希望以上內容可以對大家有一定的幫助,如果你還有很多疑惑沒有解開,可以關注億速云行業資訊頻道了解更多相關知識。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。