目錄
前言
目标
工具 - 最小的學習成本
方案 - 願景
1. 持續內建 - CI
2. 持續部署 - CD
部署環境
1. 部署gitlab-runner
2. 注冊gitlab-runner
注冊runner步驟
搭建DevOps管道 - PipeLines
1. 建立環境 - 釋出主機闆本1.1、測試
2. 滾動更新 - 疊代小版本
3. 自動伸縮
3.1、伸縮單個微服務
3.2、伸縮所有微服務
4. 復原
4.1、復原單個微服務
4.2、復原所有微服務
5. 可擴充性 - 相容新增微服務5.1、添加新的搜尋微服務
運維說明
1、分支
2、配置檔案
總結
最後
2018年既是微服務架構火爆的一年,也是容器和Kubernetes收獲贊譽盆滿缽滿的一年;在kubernetes的引領下,以容器為中心部署微服務已成為一種事實标準,并不斷加速着微服務架構模式落地,持續地發揮着它的魔力。企業,特别是網際網路公司,為了快速響應前端使用者的需求,縮短産品從需求到傳遞的周期,常常需要快速地、細膩度地疊代産品,以搶占市場先機;在微服務模式下,可以很好地滿足這個要求,隻釋出變化的服務,進而最小化單次疊代的風險,實作靈活開發和部署。
當采用微服務模式後,整個業務流程将被垂直拆分成多個小單元;每個小單元都是一個獨立開發、獨立部署和獨立擴充的微處理服務,這樣的靈活性非常适合靈活開發模式,但也給開發和運維帶來了固有的複雜性和難度。對于開發者而言,由于微服務應用整體作為一個分布式系統提供服務,需要選擇合适服務通訊協定,并處理潛在的網絡分化瞬時故障等情況,除此之外,還需要建設服務發現、配置中心等基礎設施;對于運維人員,需要利用容器的可移植性,持續地內建和部署微服務到不同的叢集環境,這些都要求運維人員具有非常全面的能力,比如:熟悉容器及k8s、能編寫Linux Shell運維腳本、熟練一種持續內建部署工具(比如:gitlab、jenkins)等。
綜上所述,如何搭建一條成熟穩定、且符合微服務特色的高度自動化DevOps管道又成為了另一個難題。
以最小的學習成本,搭建一條成熟穩定、且符合微服務特色的高度自動化DevOps管道,按需地持續內建/部署微服務到kubernetes。
kubernetes + gitlab + shell
在kubernetes的master節點部署gitlab-runner,充當gitlab伺服器的用戶端;當送出或合并代碼到指定的分支時,gitlab-runner自動從gitlab拉取代碼,利用master主機提供的邊緣計算能力來執行已編排好的DevOps CI管道=》編譯代碼、運作單元和內建測試、容器化微服務成鏡像,最後上傳到企業鏡像倉庫,這就是持續內建流程,該階段傳遞的産物為鏡像。
在kubernetes的master節點部署gitlab-runner,充當gitlab伺服器的用戶端,當持續內建階段傳遞了新版本的鏡像後,從企業鏡像倉庫拉取最新版本的鏡像,利用master主機提供的邊緣計算能力執行已編排好的DevOps CD管道=》同步服務配置資訊到配置中心(k8s的ConfigMap),并滾動更新kubernetes叢集鏡像版本。
安裝目錄:/root/gitrunner
工作目錄:/home/devops/gitrunner
在kubernetes的master節點部署gitlab-runner,指令如下:

詳情請參考: Install GitLab Runner manually on GNU/Linux。
gitlab支援注冊兩種類型的runner:
1. Specific Runners
這是隸屬于特定項目的專有勞工,不接受其他項目調遣。
2. Shared Runners
這是隸屬于gitlab-server的勞工,可以共享給所有的項目調遣。
這兩種Runner各有千秋,如果為每一個項目都注冊專用Runner,會顯得比較繁瑣和多餘,而使用共享Runner就很省事,但是一個勞工一次隻能做一件事情,當同時調遣一個勞工時,那麼就會出現競争等待,故大家還是實際情況來注冊勞工吧,隻要不延誤工期就行,嘿嘿。
在開發、預生産、生産環境注冊Runner,并貼上标簽:build、staging、prod。
備注:後面搭建DevOps管道時,将根據标簽來調遣勞工。
擷取項目位址和注冊token,依次查找路徑:Settings => CI / CD => Runners settings,如下:
注冊:
上面的方案僅僅描述了願景,也就是期望達成目标的最後結果,但對于如何落地一條真正的管道而言,還是顯得非常的空洞。其實這正是DevOps的難點,大體流程上都曉得有個持續內建、持續部署,講起來如數家珍,落地時都之乎者也。
同樣,秉承微服務的思想,分而治之,我們将管道分為兩個部分:建立、更新,即先建立一個主機闆次,然後再基于此主機闆次進行小版本疊代,不斷地擴充新功能。通過這樣有效的拆分,是不是就不那麼的空洞了,就像領域驅動設計的CQRS模式一樣,差別地對待讀寫,進而大大地減少了阻抗,也非常地切合産品的創新疊代,比如将需求拆分為3期,每一期都對應一個主版次,然後再小版本疊代每一期的需求,完成一期,封闆一期,彼此隔離,互補影響,同時也友善追溯。
理清了整個管道的脈絡,現在就需要思考一些實際問題了,比如:
1. 如何将持續內建/部署微服務流程腳本化,即如何實作基礎設施代碼化?
2. 如何動态解析git目前變化日志,實作準确地按需釋出微服務?
3. 如何保留現場,并以最小的成本重試管道?
4. 在不修改管道腳本的情況下,如何手工控制按需釋出、自動伸縮和復原微服務?
5. 如何相容新增的微服務?
6. 如何快速調試整個管道腳本?
隻有把上面的問題都處理了,才算是一條成熟可用的、企業級别的CI/CD管道,才符合高度自動化、穩定、快速、容錯等特點;在網際網路公司,可能一天要送出好幾個版本到不同的環境,不能因為考慮不周而影響連續部署的進度,管道一旦投入使用就需要對修改閉合,隻對擴充開放。
管道一覽圖:
示例項目(AspnetCore)已分享到github,請參考:MicroService.AutoDevOpsPipeLines,歡迎start,歡迎fork,歡迎issue。
為了驗證管道的特性,我特意做了以下測試:
這是一個從0到1、從無到有的過程,這裡一小步,卻是落地DevOps管道的一大步。
版本疊代的第一步就是建立微服務叢集環境,那麼如何快捷地建立這個環境呢?我将使用kubernetes的包管理器helm來完成這個任務,可能很多同學都沒用過這個工具,平時部署元件都是手工編寫好yaml資源部署檔案,雖然這種方式友善快捷,但是對于大量元件,以及需要實作基礎設施代碼化的場景,手工處理這種方式就不能滿足需求了。
模闆檔案請參考示例項目,下面是建立環境的腳本化指令:
從上面可以看出,實作部署服務腳本化的目的已經達到了。
下面我們在來看看如何腳本化整個建立環境管道線:
備注:管道線腳本請參考示例項目(AspnetCore):MicroService.AutoDevOpsPipeLines/devops/PipeLines/Creation。
将剛剛建立的helm模闆檔案上傳到gitlab-runner所在伺服器的/root目錄下,并添加配置,如下:
然後合并代碼到分支release/staging,如下:
從上面可以,第一個主機闆次(1.0.0)已經成功釋出到預生産環境。
生産環境同理,在預生産環境跑完各種測試後,合并代碼到分支release/production即可。
這個階段将模拟在第一個主機闆次(1.0.0)上進行小版本疊代需求,距離上次釋出已經一周了,開發部門也完成了第一個小版本的開發工作,現在需要釋出版本1.0.1到預生産環境進行測試,首先修改檔案version.props,如下:
除了釋出本次需求修改的兩個微服務:Identity.API、Marketing.API以外,還需強制釋出微服務Basket.API,添加配置,在gitlab倉庫依次查找 (Settings => CI/CD => Secret variables),如下:
最後合并代碼到分支staging。
先來看看是否正确解析git變更日志和全局變量,準确地實作自動化和手工控制:
再來看看整個管道的執行情況:
最後看一下預生産環境的效果
從上面可以看出,第一個小版本(1.0.1)已經按需自動釋出到預生産環境,一共滾動更新了三個微服務。如果當管道的某個階段執行異常,隻需要點選重試此階段即可;如果需要重新手工幹預,隻需要添加配置資訊,然後重試<code>analysing-git-changes</code>階段,再依次重試後面的Job即可,整個過程無需修改CI/CD管道腳本,真正實作高度自動化、快速等特點。
生産環境同理,在預生産環境跑完各種測試後,合并代碼到分支master即可。
經過一段時間的觀察發現預生産環境的購物車(Basket.API)微服務吞吐量頗高,故決定擴容它的執行個體數量到2個,首先修改項目屬性檔案deploy.props,如下:
然後添加配置,如下:
最後合并代碼到分支scaling/staging,如下:
同理,首先修改項目屬性檔案deploy.props,如下:
最後合并代碼到分支scaling/staging,或者直接重試管道的auto-scaling階段,如下:
從上面測試看到,隻需要修改配置,就可以支援不同粒度地伸縮微服務,也不用修改CI/CD管道腳本。
生産環境同理,隻需要合并代碼到分支scaling/production。
經過一段時間的觀察,發現剛剛釋出到預生産環境的版本1.0.1有問題,故決定復原到上一個版次1.0.0,首先修改項目屬性檔案deploy.props,如下:
然後添加配置(隻復原購物車微服務),如下:
最後合并代碼到分支rollback/staging,如下:
然後添加配置復原所有微服務,如下:
最後合并代碼到分支rollback/staging,或者直接重試管道的roll-back階段,如下:
生産環境同理,隻需要合并代碼到分支rollback/production。
經過一段時間的疊代,一期已經完工,二期新增了搜尋微服務,這時修改helm模闆檔案支援部署搜尋微服務,然後合并代碼到release/staging,測試如下:
k8s
網關路由
從上面可以看到,新增的搜尋微服務已經成功釋出到第二個主版次了。除了修改helm模闆檔案以外,整個過程并沒有修改CI/CD管道腳本,圓滿完成了相容新增微服務的特性。
備注:我們可以将helm模闆看成服務編排檔案。
build
建構和編譯代碼。
release/staging
建立預生産環境。
staging
滾動更新預生産環境。
release/production
建立生産環境。
master
滾動更新生産環境。
scaling/staging
伸縮預生産環境
scaling/production
伸縮生産環境
rollback/staging
復原預生産環境
rollback/production
復原生産環境
應用程式配置 - app.props
版本配置 - version.props
部署配置 - deploy.props
特定環境配置,如:deploy.staging.props
分支環境配置 - branch.env.props
上面的測試幾乎涵蓋了結合k8s管理應用生命周期的所有流程(部署、伸縮、復原、釋出),大家可以放心地運用或者擴充這個管道到自己的微服務項目中,比如:目前僅支援自動建立路由到kong網關,建議大家fork項目後,自行擴充,測試完成後,也可以提取PR。如果你采用示例一樣的項目結構,隻需要修改配置資訊,然後開箱即用。
如果你有什麼需求無法實作,歡迎加入QQ群:564095699,一起探讨k8s實踐微服務的方方面面。
如果有什麼疑問和見解,歡迎評論區交流。
如果你覺得本篇文章對您有幫助的話,感謝您的【推薦】。
如果你對微服務實踐感興趣的話可以關注我,我會定期的在部落格分享我的學習心得。
歡迎轉載,請在明顯位置給出出處及連結。
做一個有底蘊的軟體工作者