1. 程式人生 > >DevOps平臺中的自動化部署框架設計

DevOps平臺中的自動化部署框架設計

本文轉自微訊號EAWorld。掃描下方二維碼,關注成功後,回覆“普元方法+”,將會獲得熱門課堂免費學習機會! 圖片描述
本文目錄:
一、背景
二、我們的需求是什麼?
三、概念澄清
四、概念模型
五、總體設計
六、關鍵點設計
七、總結

一、背景

說到自動化部署,大家肯定都會想到一些配置管理工具,像ansible,chef,puppet, saltstack等等。雖然這些工具給運維效率和安全性帶來了很多好處。但是實際工作中,我們還是會遇到一些問題:

這些工具無法普及到開發、測試人員,經常找運維幫忙,無法自助;
專案人員無法直觀的參看到系統的部署架構設計,及架構的演進過程;
從物理架構設計到最終上線,無法形成閉環;
受差異性的基礎設施影響較大。

二、我們的需求是什麼?

我們DevOps平臺的部署模組就克服上面這些問題,為實現DevOps以產品為核心,以專案管理為驅動,將需求、設計、交付、運維整個鏈路打通這一目標提供有力支援。具體來看其需求涵蓋一下幾點:

將架構設計納入DevOps管理過程中,支援架構設計版本化;
一次架構設計多次部署;
以最佳實踐為基礎,實現架構設計模版重用;
多環境部署,同時支援應用在虛擬機器、容器上的部署;
支援多種部署模式(單機、高可用)、部署策略(全新、藍綠、滾動升級、回滾)

三、概念澄清

在正式講解我們的設計之前,我們想澄清CI/CD的基本概念,因為本次的主題和持續整合、持續交付和持續部署這些名詞總有些淵源。

1、什麼是持續整合?

持續整合(Continuous Integration)指的是,頻繁地將程式碼整合到主幹,以便快速發現錯誤、防止分支大幅度偏離主幹。

持續整合的目的,就是在產品快速迭代的同時保持程式碼質量,它的核心措施主要有兩點:
1)程式碼整合到主幹之前,必須通過自動化測試,只要有一個測試用例失敗,就不能整合。
2)通過Code Review、程式碼質量分析工具對程式碼質量進行把關,以便確定是否能夠整合。

Martin Flower說過, “持續整合並不能消除Bug,而是讓他們非常容易發現和改正。”

2、什麼是持續交付?

持續交付(Continuous Delivery)指的是,新版本為了能夠快速安全的交付到生產環境中,需要將新版本先交付到類生產(Production-like)環境中(如UAT/Staging/Lab環境),以便進行相應的業務驗證、安全驗證、效能驗證等過程。

一旦類生產環境驗證通過,新版本就進入到生產階段。

持續交付可以看作是持續整合的進一步。它強調的是,不管怎麼更新,軟體是隨時隨地可以交付的。

3、什麼是持續部署?

持續部署(Continuous Deployment)指的是,新版本通過類生產環境的驗證後,自動部署到生產環境中。

持續部署可以看成持續交付的進一步。持續部署的前提是自動化完成測試、構建、驗證等步驟。

持續部署的目標是,程式碼在任何時刻都可以進入自動地進入生產階段,為終端使用者提供服務。

持續交付和持續部署的區別可以參考下圖:圖片描述

從上圖中,我們可以看出:
持續交付流程將自動的測試新版本應用,但是否將新版本交付到生產環境中是一個手動過程。持續部署則是自動地將新版本交付到生產環境中去。

關於持續交付/持續部署,我們不能說哪一個是最好的方案。對於不同的組織,適合的就是最好的。

4、什麼是自動化部署?

自動化部署(Automatic Deployment)指的是,通過自動化工具將應用介質部署到指定環境中去。
自動化部署只是持續交付和持續部署流程中的一個功能單元。
自動化部署工具:Ansible、Puppet、SaltStack等等。

通過以上概念的澄清,我們瞭解了什麼是持續整合、持續交付、持續部署以及自動化部署。
本文的主題不是介紹持續整合、持續交付、持續部署的Pipeline與實現,而是介紹DevOps平臺中,在傳統自動化部署工具之上的自動化部署框架的設計與實現。而自動化部署模組也是我們DevOps平臺中的CI/CD的底層能力。

下面我們就來聊聊具體的設計。

四、概念模型

圖片描述

除了系統內建的一些模版概念,我們將自動化部署流程分為三個階段,即設計、轉換、運維。每個階段都會有相應的基本模型。
下面,我們分階段的去解釋一下這些概念模型。

1、設計階段

設計(Design),是在裝配(Assembly)內對應用/系統的架構的描述;而應用/系統,是由含有多個元件(Component)的系統(Platform)組成的。
Design階段的基本流程:

(1)建立裝配(Assembly)
通過選擇可用的系統模版(Platform Template),新增一個新的Platform;
每一個Platform都對應一種應用(如mysql,tomcat,springboot,nginx);
每一個Platform都是有一組元件(Component)組成的,並且已定義好了元件之間的依賴關係;
在Assembly內,使用者可以通過設定Platform Link設定各個Platform之間的關係

(2)配置系統(Platform)內的元件(Component)的屬性值
Component是最底層的部署(或者配置)單元,如springboot中的secgroup, compute, os, jdk, fatjar, lb都是一個元件;
每一個Component都有相應的配置模版

(3)提交設計
提交的過程是將已經完成的設計做一次Commit,做一次歸檔。

2、轉換階段

轉換(Transition),是在Assembly內對應用/系統在某一Environment內的部署過程。
Transition階段的基本流程:

(1)建立部署環境(Deploy Environment)
根據環境型別(如dev, test, prod等),新增屬於某個Assembly的部署環境
部署之前,部署環境是應用/系統用於部署的配置的抽象
部署之後,部署環境就是管理和監控應用/系統的具體例項的集合

(2)配置部署環境
設定每個Platform關聯的資源(vm/container)、部署模式(單點,高可用)

(3)選擇Assembly內的一個或多個Platform生成並提交執行計劃
根據部署策略不同,一個Platform的執行計劃可能包含幾個子計劃

(4)執行部署
每個Assembly/Environment/Platform下面的每個Component都有一個instance,這些instance可以進行單獨Repair

3、運維階段

運維(Operation),是在Assembly內對各個部署環境內Instances的管理和監控。
Operation階段的基本任務:

(1)元件例項運維,例如
Compute: Status, Reboot, upgrade-os-security, powercycel, repair, upgrade-os-all
Tomcat/Jboss: Status, Stop, Start, Restart, Repair, Debug
Artifact: Repair, Redeploy, Custom User Attachment

(2)展現正在部署的操作,有可能還會Replace或Cancel其中一項元件部署或整個部署

(3)展示Assembly某一Environment下的元件例項圖譜

(4)日誌查詢
對基本的概念模型有了基本認識後,我們來看一下自動化部署框架的總體思路。

五、總體思路

DevOps自動化部署框架採用DevOps平臺(設計)+Jenkins(執行)的方式完成。

DevOps的職責
完成部署架構設計;
根據部署架構設計和部署環境的配置建立生成相應的執行計劃及子執行計劃,每一個子計 劃對應一個Jenkins pipeline job配置檔案(config.xml);
查詢Jenkins執行job的實時進度與結果。

Jenkins的職責
根據config.xml建立Jenkins Pipeline Job;
執行pipeline job;
Jenkins job 通過pipeline script中ansible/openshift命令進行相應的部署等執行操作;
提供查詢job執行情況的Rest API。

結合上面提到的三個階段,具體的流程如下所示:圖片描述

下面是具體的部署檢視:圖片描述

看完整體思路和部署檢視,大家肯定會問為什麼選擇jenkins作為具體的執行引擎?
首先,jenkins支援master/slave架構,能根據效能需求水平擴張,slave又可以支援多種環境,可以將不同的job分配到不同的slave節點。

還有非常重要的一點,就是Jenkins Pipeline的能力。
Jenkins中pipeline的設計理念是實現基於groovy指令碼,靈活,可擴充套件的工作流。

durable永續性:在jenkins的master按計劃和非計劃的重啟後,pipeline的job仍然能夠工作,不受影響。
可暫停性:pipeline基於groovy可以實現job的暫停和等待使用者的輸入或批准然後繼續執行。
更靈活的並行執行,更強的依賴控制,通過groovy指令碼可以實現step,stage間的並行執行,和更復雜的相互依賴關係。
可擴充套件性:通過groovy的程式設計更容易的擴充套件外掛。
豐富外掛:Jenkins已經支援通過groovy命令呼叫git、maven、npm、gradle、shell、junit、sonarqube、ansible、docker、openshift、kubernetes等外掛,不需要我們再單獨實現整合。
Rest API:Jenkins提供通過Rest API的方式獲取每一個stage的執行情況。

由於我們最終會將應用部署到虛擬機器和容器雲中,虛擬機器部署主要通過jenkins中提供的ansible外掛+jenkins pipeline script來實現;容器雲部署則根據具體的容器雲,通過openshift外掛(會有一定擴充套件)或者http request外掛+jenkins pipeline script來實現。

下面我們來看一下Jenkins2的主要概念。

step, 其實跟jenkins1中的概念一樣, 是jenkins裡job中的最小單位,可以認為是一個指令碼的呼叫和一個外掛的呼叫。比如通過git拉取程式碼就是一個step,mvn clean package也是一個step,一個http遠端呼叫等等。

node, 是pipleline裡groovy的一個概念,node可以給定引數用來選擇agent,node裡的steps將會執行在node選擇的agent上。這裡與jenkins1的區別是,一個 job裡可以有多個node,將job的steps按照需求執行在不同的機器上。例如一個job裡有好幾個測試集合需要同時執行在不同的機器上。

stage, 是pipeline裡groovy裡引入的一個虛擬的概念,是一些step的集合,通過stage我們可以將job的所有steps劃分為不同的stage,使得整個job像管道一樣更容易維護。pipleline還有針對stage改進過的view,使得監控更清楚。這裡補充一句,多個stage可以在一個node裡定義及執行,一個stage內的多個step可以分到不同的node上執行。

六、關鍵點設計

前面我們說的都是概念和流程上的東西,那麼使用者該如何進行部署架構設計?部署架構設計完成後,如何提交呢? 如何將提交的設計在具體的部署環境中轉換成執行計劃與子執行計劃呢?子計劃又如何與jenkins pipeline job對映呢?這就是我們下面要介紹的一些關鍵點設計。

1、模組化
圖片描述

前面提到,當用戶建立Platform時,我們的DevOps平臺提供可選的Platform Template,Platform Template定義了其中可以包含的元件型別(Component Template)等資訊。也就是說,我們的平臺提供了一種基於最佳實踐的方式,幫助使用者完成系統的架構設計。不僅如此,通過對Platform Template/Component Template等相關資料準備的介紹,也對以後使用者擴充套件新增新的元件型別,提供了充足依據。基本思路如下:

1)定義不同的系統模版Platform Template(見表DPS_DLV_PLATFORM_TEMPLATE)。系統模版就是我們通過最佳實踐的方式提供了一套應用/中介軟體系統的模版。如tomcat,nginx、springboot、mysql等。
一個Platform Template定義了這個模版中包含的元件模版,定義了元件模版之間的依賴關係(見表DPS_DLV_COM_RELATION_DEFINITION),以及每一種元件型別所在的層以及每一種元件型別允許新增的元件的個數(見表DPS_DLV_COMP_CONTAINER_DEFINITION)。當用戶新增一個Platform時,必須要選擇一種Platform Template。

2)根據不同的部署模式(單節點、高可用)、不同的目標資源(虛擬機器、容器)、不同的部署策略(全新、藍綠、滾動升級、回滾),一個系統模版會對應到多個執行計劃模版 (見表DPS_DLV_PLATFORM_ACTION_PLAN_TEMPLATE)。

3)一個系統由多個元件組成,因此係統模版和元件模版之間也是多對多的關係。例如springboot模版對應的元件模版有:secgroup模版、os模版、jdk模版、java application模版等等。

元件模版Component Template(見表DPS_DLV_COMP_TEMPLATE)以及元件的所有屬性(見表DPS_DLV_COMP_ATTRIBUTE_DEFINITION)。元件模版就是元件的元資料,為Platform新增的Component都是源於Component Template。

4)為每個Component Template定義Operation模版(見表DPS_DLV_COMP_OPERATION),以便對單個元件例項進行操作,如restart, repair, stop等。

通過以上4步系統預置的Platform Template和Component Template以及相應的資料,就可以提供給使用者新增一個Platform了。這些預置資料也為後面生成部署計劃Deploy Plan做好的準備。

2、變數管理

在需求分析中,我們就提出希望一次設計多次部署。但是在設計階段設定各個元件屬性時,並不能確定在不同的部署環境中其值是一致的,並且一個系統的不同元件的屬性也可能是共用一個值。這時候我們就需要引入變數管理。變數管理的主要思路如下:

1)設計階段,為系統定義一些變數(ConfigMeta)並設定一個預設值,如install_dir。然後在設定某個元件屬性值時可以用@P{install_dir}來表示。

2)提交設計時,也一同將變數定義作為設計的一部分進行提交。

3)轉換階段,在部署環境中,為每一個變數設定當前環境下的值(ConfigValue)。當建立執行計劃時,會將屬性@P{install_dir}替換為當前環境的值。

不僅Platform內可以定義變數供該Platform下的Component使用,我們也可以給Assembly定義變數供所有Platform及其元件使用, 形如@A{assembly_var}。

3、設計提交
圖片描述

當用戶設計完部署架構、設定每個元件屬性及變數後,需要將當前的設計指定好版本進行提交,即歸檔。只有提交的設計,才能在部署環境中獲取的到指定的版本。通過版本化,我們可以設計的不同版本做相關的對比。

上面的表結構是比較清晰的表述。

4、執行計劃

根據不同的部署模式(單節點、高可用)、不同的目標資源(虛擬機器、容器)、不同的部署策略(全新、藍綠、滾動升級、回滾),一個系統模版會對應到多個執行計劃模版,並且計劃模版之間有父子關係。
每一個子執行模版就是一個jenkins pipeline script模版。
當用戶在部署環境中選擇某個具體系統及部署策略生成相應的執行計劃(含子計劃)時,每一個子計劃的jenkins pipeline script就是將具體的元件屬性注入到執行模版中生成的。

另外,為什麼需要顯示的創建出子計劃呢?例如,對於一個高可用的應用,除了要部署具體的應用,還需要更新load balance配置,而這兩者之間可能需要加入一些人工活動。所以我們通過顯示的建立處子計劃,支援使用者按子計劃一步步的來做。

而jenkins pipeline script的stage幾乎都對應到一個具體的元件,具體可以看下圖。**圖片描述**

5、部署策略

前面我們提到了“部署策略”這個詞,除了全新部署,我們常見的部署策略有藍綠髮布、滾動升級、灰度釋出/金絲雀釋出、回滾。下面來看看我們的相應解決方案。每一種部署策略都會有相應的執行計劃模版(含子計劃)。

藍綠髮布

什麼是藍綠髮布?
在釋出的過程中使用者無感知服務的重啟,通常情況下是通過新舊版本並存的方式實現,也就是說在釋出的流程中,新的版本和舊的版本是相互熱備的,通過切換路由權重的方式(非0即100)實現不同的應用的上線或者下線。

前提條件
雙份資源 or 支援雙埠模式
負載均衡服務 + 操作API介面

實施方案
第一步,設定系統將要部署的資源列表。
第二步,將新版本部署容器部署到資源列表中。
第三步,呼叫負載均衡服務的API介面更新負責均衡配置。第四步,更新資源的標籤。

考慮到使用者可能會手工介入確定是否需要更新負載配置,我們會將第二步、第三步分為兩個子執行計劃。

滾動升級

什麼是滾動升級?
滾動釋出,一般是取出一個或者多個伺服器停止服務,執行更新,並重新將其投入使用。周而復始,直到叢集中所有的例項都更新成新版本。
這種部署方式相對於藍綠部署,更加節約資源——它不需要執行兩個叢集、兩倍的例項數。我們可以部分部署,例如每次只取出叢集的20%進行升級。

前提條件
負載均衡服務 + 操作API 介面

實施方案
第一步,設定滾動升級係數(步進),如20%/n個。
第二步,依次將20%的部署容器移除負載,然後在原資源處部署新版本,然後加入負載。

灰度釋出/金絲雀釋出

什麼是灰度釋出/金絲雀釋出?
灰度釋出是增量釋出的一種型別,它的執行方式是在原有軟體生產版本可用的情況下,同時部署一個新的版本。同時運行同一個軟體產品的多個版本。
其實,灰度釋出是滾動升級的一種變體,其實灰度釋出是先劃分出新版本的路由權重,新版本在真實資料驗證通過後,在進行剩餘老版本的升級。

前提條件
負載均衡服務 + 操作API 介面

實施方案
第一步,設定新老版本的路由權重,如90%的使用者維持使用老版本,10%的使用者使用新版本。
第二步,將10%的部署容器移除負載,然後在原資源處部署新版本,然後加入負載。
第三步,待真實資料驗證通過後,再進行剩餘老版本的滾動升級。

回滾

什麼是回滾?
回滾是指將應用/服務回退到上一可用版本,並使之可用。
我們暫時只支援針對藍綠髮布的回滾。

前提條件
新版本是基於藍綠髮布策略完成的部署。
負載均衡服務+操作API介面。

實施方案

更新負載配置

七、總結

本文大致向大家介紹了我們的DevOps平臺中自動化部署框架的相關設計,主要簡單介紹了實現思路和幾個關鍵點。 其中還有很多細節,比如如何與CMDB整合,如何與各種容器雲集成,以及我們實踐過程中遇到的各種坑等等,這裡不再一一贅述。

關於作者:
許二虎
EAII-企業架構創新研究院 專家委員
現任普元雲端計算高階工程師。畢業於中國科學技術大學,軟體工程碩士。曾任職於群碩軟體、科緯迅軟體服務、平安健康,具備網際網路領域的技術應用經驗。在普元雲端計算平臺中的角色是,以靠譜的後端的功底,支撐著整個DevOps業務平臺交付。圖片描述
關於EAWorld
微服務,DevOps,元資料,企業架構原創技術分享,EAii(Enterprise Architecture Innovation Institute)企業架構創新研究院旗下官方微信公眾號。

掃描下方二維碼,關注成功後,回覆“普元方法+”,將會獲得熱門課堂免費學習機會!
微訊號:EAWorld。 圖片描述
全新形態的PWorld2017盛大開啟,首四場定於7月1日在北京、上海、廣州、成都四城同步舉行。CSDN專項報名通道可獲得現場伴手禮個性T恤一件!