歡迎光臨
每天分享高質量文章

騫雲科技DevOps實踐

隨著公司業務的快速發展,需要加快開發流程的規範化和自動化,以提高產品的開發效率和交付效率。之前的開發測試和資源管理主要是半自動化的,個人生產力和資源利用率仍有很大提升空間。在DevOps的具體實踐中,一方面, Gerrit + GitLab + Jenkins + CMP(Ansible)共同構建了更好的 CI/CD 流程,對自動化持續交付流水線進行了優化;另一方面,CMP(Self-Service Portal)幫助建立了自服務自運維門戶,公司所有人員都可以通過統一的門戶自助申請各類資源,並自助完成日常運維。
為什麼我們要加強 DevOps?

 

在公司創立早期,為了儘快實現產品從0到1的轉化,我們將更多的資源投入到了產品的新功能開發上,在產品開發自動化方面的投入並不高。
隨著公司業務的迅速發展,一方面,團隊規模不斷擴大,服務器資源也越來越多;另一方面,產品的功能逐漸豐富,開發代碼工程數和分支數增加,而開發測試和資源管理仍以半自動化為主。
面臨的問題:
人力資源浪費
手工打包、手工創建虛機、手工部署、手工升級、較低程度的自動化測試,這些重覆且低效的開發測試樣式導致開發測試人員不能將寶貴的時間用於更加有創造力的工作上,不利於個人和公司的快速發展。
IaaS資源管理混亂
我們的開發測試環境主要構建在內部的vSphere和OpenStack雲臺上,當然也會在Aliyun、AWS、Azure等公有雲上創建資源。在日常工作過程中,我們經常會聽到這樣的聲音:“我的環境怎麼這麼卡”、“阿裡雲上又沒錢啦”、“OpenStack上的機器我要刪了啊”、“誰刪了我的機器,我的資料還在上面呢”。由於沒有權限控制導致資源隨意創建,資源不及時釋放導致大量資源閑置和浪費,另外還存在資源誤刪除情況。
內部系統運維成本居高不下
我們沒有專職的內部系統運維人員,平時開發過程中,遇到CPU/Memory調整、磁盤物理捲/邏輯捲擴容、操作系統故障、應用故障等一系列問題都會占用研發人員大量的時間和精力。
產品交付難度大
為滿足穩定性、高可用性、可擴展性等交付需求,我們的產品在軟體架構設計上具有較高的複雜度,這樣一來安裝部署實施的難度也就比較大。售前團隊到客戶現場做POC,想要快速部署一套公司產品比較困難;售後團隊在專案交付的過程中也經常遇到各種各樣的安裝配置問題。
基於上述問題,我們希望通過對DevOps工作流程進行改造和增強,以提高產品開發效率和交付效率,以及提升個人生產力和資源利用率。

 

DevOps整體規劃

 

我們將DevOps工作流程改造分為了兩個方面,一個是對CI/CD工作流的優化,一個是搭建自服務自運維門戶。
CI/CD標的
  • 所有代碼工程能夠自動化打包

  • 所有代碼提交後能夠自動構建編譯檢查以及單元測試任務

  • 每小時完成一次軟體集成、部署以及核心功能的集成測試(API&UI;)

  • 每天完成一次完整功能的集成測試(API&UI;)

  • 每周完成一次7×24小時Longrun系統測試

  • 自動更新經過測試的nightly build到開發測試環境

  • 自動發佈經過測試的weekly build到Demo環境

 

自服務自運維標的
公司所有人員,都可以通過一個統一門戶Portal,自助申請各種型別的IaaS資源,如: x86物理服務器、vSphere虛擬機、OpenStack虛擬機、Kubernetes上的容器服務,以及Aliyun、AWS、Azure等公有雲上的雲資源;自助申請日常開發所需的軟體應用,如:Nginx、Tomcat、MySQL、RabbitMQ,以及SmartCMP等。
  • 開發Dev,測試QA,售前交付需要使用不同的資源,做到資源隔離;

  • 資源的使用需要有權限控制;

  • 需要能夠一鍵部署單節點和HA多節點應用系統;

  • 提供環境自動初始化,一鍵升級能力;

  • 提供系統和應用級別的監控告警;

  • 資源需要能夠定期回收。

構建更好的CI/CD流程

 

概述
我們的DevOps工具鏈由 GitLab、Gerrit、Jenkins、CMP 構成。
  • GitLab:代碼托管

  • Gerrit:代碼審查

  • Jenkins:單元測試、自動化打包、集成測試

  • CMP:vSphere、OpenStack、Kubernetes等雲資源統一管理,應用系統自動化部署,版本更新

具體的工作流如下圖所示:
開發人員提交代碼後,觸發Jenkins完成代碼編譯檢查和單元測試,Jenkins傳回代碼檢查結果給Gerrit,人工Review後merge代碼,觸發Jenkins完成該專案的打包。Jenkins定時完成各個工程的集成打包,然後通過呼叫CMP的API觸發自動化部署,部署完成後進行場景化的集成測試,測試完成後卸除資源。

持續集成(Jenkins)
起初我們使用GitLab Runner實現CI,在每個代碼工程中添加“.gitlab-ci.yaml”檔案,不同專案各自創建和維護自己的.gitlab-ci.yaml腳本,這樣的實現可以解決各自工程的編譯測試和打包問題,在代碼工程數量較少時,我們也使用了較長一段時間。
現在我們的代碼工程數量已超過20個,每個代碼工程都設置了訪問權限,如果需要專人維護CI腳本的話,那他需要能夠訪問所有代碼工程,顯然這樣是不合理的,而且把集成打包腳本放在哪個工程里都不合適。
考慮到Jenkins有強大的CI能力:通過安裝插件就能快速與Gerrit、GitLab集成,能夠引數化執行各種型別的腳本。所以,我們使用Jenkins代替gitlab-runner完成CI,通過Jenkins可以統一管理各個工程的編譯、測試、打包,而且比較方便構建流水線完成較多工程集成打包及測試。

持續部署(Ansible)
我們的產品由20多個服務組成,可部署在一個或多個虛擬機上,使用Shell腳本或Python腳本已經很難完成這麼多服務程式的自動化安裝部署配置。
恰巧團隊有使用Ansible做複雜系統部署的經驗,Ansible的學習成本也較低,所以我們選擇使用Ansible Playbook 實現這20多個服務程式的統一編排部署和配置,並且可以同時支持單節點和HA多節點自動化部署。
下圖是Ansible自動化部署拓撲圖:

我們設計Ansible Playbook時,將每個服務都獨立成一個角色,這樣保證了各個服務部署的獨立性,這種分佈式部署架構為將來容器化部署和微服務化奠定了基礎。
Ansible自動化標準化部署不僅大大縮短了部署時間,也極大地降低了部署出錯的概率。原先,按照HA架構部署一套產品需要1天時間來完成各個服務的部署和配置,通過使用Ansible playbook,我們只需要45分鐘,而且中間過程完全可以放手去做別的事情。
集成測試(Robot Framework)
目前,我們在Jenkins中使用Robot Framework框架做集成測試。Robot Framework(以下簡稱RF)是一個基於Python的、可擴展的、關鍵字驅動的測試自動化框架。
選用RF的原因:
  • 一致性:目前公司的UI自動化測試使用的就是RF框架,RF框架也完全有能力做集成測試,因此使用RF框架做集成測試,可以降低學習成本,提高可維護性。

  • 復用性:在安裝了Robot-Framework-JMeter-Library後,RF可以運行JMeter腳本,並且將JMeter運行結果轉為Html格式。公司目前性能測試用的就是JMeter,對於相同場景,只要小幅修改JMeter腳本即可將其復用到集成測試上面。

 

選用RF也存在一些問題:
  • 如果不復用JMeter腳本,編寫的API測試用例的成本非常高。 RF對於變數型別的規定堪稱僵硬(當然,這麼規定帶來的好處是方便型別檢測),RF中對於字典型別的創建非常麻煩(嵌套的字典實體如下),對於我們公司API請求中攜帶大量引數的情況,只能創建關鍵字來解決,不管是採取RF自帶創建字典的方法,還是創建關鍵字的方法,都比較浪費時間(因為難以復用)。

     

  • RF可以輕鬆擴展關鍵字,也因此可能帶來亂擴展關鍵字的問題,導致測試用例可讀性和可維護性差的問題。

在RF中,關鍵字其實就是Python/Java的類方法,因此擴展起來非常容易,但是關鍵字一旦多起來,一個同事寫的測試用例,其他人(甚至他自己過了一段時間)維護就非常麻煩(需要回去看關鍵字是如何規定的)。因此需要嚴格規定關鍵字的創建規範是一件值得深入討論的事情。
建立自服務自運維門戶

 

我們使用雲管理平臺(以下簡稱CMP,Cloud Management Platform)管理公司內部資源,使得公司所有人員,都可以通過CMP提供的自服務門戶(Self-Service Portal),完成計算/儲存/網絡等IaaS資源和軟體應用自助申請,並且能夠自助進行日常運維操作。
CMP平臺準備工作
通過LDAP方式將公司AD賬戶匯入CMP平臺中,為開發、測試、售前售後團隊創建不同的業務組和資源池,每個資源池給到不同的資源配額,做到資源合理分配和資源相互隔離。為每個業務組設定一個管理員,審批業務組成員的資源申請。

我們使用Shell、Python腳本或Ansible配置管理工具將內部常用的一些軟體及應用系統的安裝過程進行封裝,併發布到CMP平臺中,提供標準化藍圖方便大家申請。

自服務自運維門戶
在門戶中,大家可以看到已經發佈好的服務卡片,通過點擊服務卡片即可完成IaaS資源或應用系統的自助申請,在平時的開發測試過程中,我們不再需關心底層複雜的系統或網絡配置。

在門戶中,大家也可以清晰地看到自己所管理的資源的性能情況,還可以簡單便捷地完成一些日常的基礎運維操作:重啟、調整配置、添加邏輯捲、擴展邏輯捲等。
此外,使用管理賬號登錄CMP管理平臺,可以清晰地看到公司內部資源的總體使用情況。

 

總結與建議

 

在騫雲科技的DevOps實踐中,一方面,我們將GitLab、Gerrit、Jenkins、Ansible、JMeter、Robot Framework等成熟的開源工具開源技術和企業內部的雲管理平臺相結合,實現了較高程度的開發測試流程自動化,推動了產品的持續集成和持續交付,減少了大量的重覆勞動,提高了開發測試效率。
另一方面,通過使用雲管理平臺,將複雜異構的IaaS資源服務化,降低了使用難度;結合業務部門需求合理劃分資源,減少了資源浪費,加強了資源的有效隔離,避免了誤操作;自服務自運維的樣式,也極大地提升了公司整體研發效率。
我們的DevOps實踐方案適用的場景非常多樣,比如:彈性伸縮、遷移、負載均衡。在傳統IT、金融、互聯網、游戲等行業也具有普適性。

 

未來發展方向

 

在介紹Ansible自動化部署時有提到,我們的業務系統由20多個服務組成,符合服務化的架構設計,目前已經可以滿足私有化的部署需求。隨著新功能的不斷引入,部分業務子系統複雜度和團隊開發耦合度會逐漸升高,協作效率和部署效率會變得低下。另外,當前的軟體架構和部署架構不能滿足將來的SaaS化部署。所以,我們仍需要將服務進行更細粒度的拆分,逐步向微服務架構轉變並使用容器化部署,進一步降低開發和部署成本。
Q&A;

 

Q:CMP和各個雲平臺打通都使用了平臺的jar,並且需要各種資源生成,這個工作量也不小吧?並且如果api更新代碼量也大吧?
A:我們的核心業務就是做雲管理平臺,我們產品已經完成了對各個雲平臺的對接,主要呼叫各個雲平臺的API。公有雲的API更新頻率並不是很高,每當API有更新時,我們也及時去適配。
Q:Jenkins初次提交也能觸發構建嗎?每次自動化構建版本號是如何更新的呢?
A:我們的專案代碼具備構建條件後,才在Jenkins上創建了專案構建Job,所以並沒有在初次提交時觸發構建。每次構建的版本號由兩部分組成,一部分是產品的Release大版本號,另一部分直接使用的Jenkins build number這個環境變數。
Q:有了Gerrit,為什麼還要GitLab,Gerrit也可以托管代碼啊?
A:這個是有歷史背景的,我們是先選擇使用GitLab做代碼托管,後期才加入Gerrit做code review。Gerrit在代碼review方面比GitLab的merge request要方便許多,更適合企業內部使用。關於這個,我的想法是,要麼將GitLab遷移到Gerrit,要麼不用Gerrit,可以使用GitLab的merge request來進行review,那GitLab其實是可以不要的。

赞(0)

分享創造快樂