(2022.07.27 Wed)
在軟件工程中,CI/CD或CICD是持續(xù)整合(Continuous Integration)和持續(xù)交付(Continuous Delivery)或持續(xù)部署(Continuous Deployment)的聯(lián)合實踐。CI/CD通過對構建(building)呀舔、測試和部署的自動化谎仲,在開發(fā)和運營(operations)之間的建起了橋梁太颤。CI/CD服務編譯開發(fā)者提供的增量代碼更新谨垃,并將其連接和打包成可交付的軟件服務。自動化測試驗證軟件的功能性窖式,而自動化部署將軟件送到終端使用者面前。CI/CD的目的是在開發(fā)早期發(fā)現(xiàn)瑕疵动壤、提升生產力和提供更快的發(fā)布循環(huán)萝喘。在傳統(tǒng)的軟件開發(fā)流程中,軟件更新被整合成一個大的批處理(one large batch),并部署成新版本阁簸;而現(xiàn)代DevOps實踐中弦蹂,持續(xù)開發(fā)、測試强窖、整合凸椿、部署和檢測貫穿在開發(fā)周期的始終。CI/CD流程形成了現(xiàn)代DevOps操作的主要力量翅溺。
CI持續(xù)集成
傳統(tǒng)軟件開發(fā)流程中脑漫,多個開發(fā)者產生代碼,并在發(fā)布前將他們的工作整合在一起咙崎。如果代碼中出現(xiàn)問題或整合時產生問題优幸,將不得不通過長時間的測試才可解決,之后才能正常發(fā)布褪猛,常常導致了軟件品質問題和更新周期過慢网杆。
持續(xù)集成皆在通過敏捷開發(fā)流程解決上面問題。持續(xù)集成指開發(fā)者對代碼的每個修改都被迅速整合進軟件的主分支(main branch)伊滋。CI系統(tǒng)自動運行測試以找出代碼的問題碳却,開發(fā)者得到了快速反饋并可盡快解決問題。一個新的功能只有在整合進主分支笑旺、與其他代碼修改整合在一起昼浦,才被認為開發(fā)完成。
技術上筒主,團隊通過部署一個構建服務器(build server)來實現(xiàn)CI关噪,該服務器可以承接代碼修改、使用多種整合工具實現(xiàn)自動化測試乌妙、整合代碼修改到主分支使兔,并創(chuàng)建軟件的新版本。
CI戲劇性的提升了軟件開發(fā)的品質和速度藤韵。團隊可以迅速的創(chuàng)建新的功能虐沥。
CD持續(xù)交付continuous delivery
部署新的軟件發(fā)布曾經是相當有風險和復雜的事情。新的發(fā)布被測試之后荠察,運營團隊將其部署在生產環(huán)境置蜀。部署的過程可能會持續(xù)數(shù)小時,或數(shù)周悉盆,這取決于軟件的規(guī)模盯荤、checklist和手動步驟以及對操作人員的專業(yè)要求。如果部署經常失敗焕盟,會需要迂回方案(workarounds)或需要開發(fā)者的緊急支援秋秤。
傳統(tǒng)的部署過程有諸多挑戰(zhàn)宏粤,如團隊壓力大、組織承擔過高風險灼卢、在生產環(huán)境中引入了bugs等绍哎。
持續(xù)交付CD旨在用自動化的方式解決這些挑戰(zhàn)。在CD方法中鞋真,軟件被盡可能頻繁的打包和部署到生產環(huán)境中崇堰。CD的核心原則是對代碼的每一次修改被部署到生產環(huán)境中不會花費太多功夫。
在CI系統(tǒng)整合代碼變更并穿件系統(tǒng)的新版本之后涩咖,CD系統(tǒng)將新軟件版本打包海诲、部署在測試環(huán)境、自動化地測試運行效果檩互,并將其推送到生產環(huán)境特幔。最后的推送步驟由人工驗證,但并不需要過多人工的工作闸昨。
實現(xiàn)CD需要整個軟件開發(fā)周期的自動化蚯斯,包括構建、測試饵较、環(huán)境設置和軟件開發(fā)拍嵌。所有的artifacts都在代碼倉庫中,并應當針對創(chuàng)建和更新環(huán)境設置自動化機制告抄。
CD流程帶來明顯收益 - 允許開發(fā)團隊立即為客戶提供價值并創(chuàng)建真正的敏捷開發(fā)流程撰茎。
注意持續(xù)交付和持續(xù)部署都是CD,他們的區(qū)別在于開發(fā)者可以持續(xù)交付打洼,但運營團隊可以有選擇性的部署或按批次部署。
CI/CD基本流程
CI/CD流程(CI/CD pipeline)是一個框架逆粹,該框架強調敏捷DevOps團隊的迭代化的募疮、可靠的代碼交付。該框架中的工作流包括持續(xù)集成僻弹、測試阿浓、交付、部署蹋绽。該流程將這些步驟安排/整合成一個開發(fā)高質量軟件的標準流程芭毙。
測試和構建的自動化是CI/CD pipeline的重要一環(huán),這兩個步驟可以幫助開發(fā)者在SDLC的早期確定代碼問題并解決卸耘,之后可以更容易的將代碼推送到不同的環(huán)境中并將其推送到生產環(huán)境退敦。自動化測試包括性能測試(壓力測試)、安全測試(靜態(tài)安全測試)等蚣抗。
除了測試和品控侈百,自動化也應用于CI/CD全程的各個階段,可幫助開發(fā)者提供穩(wěn)定的軟件,使發(fā)布流程更加快捷和安全钝域。
(2022.07.28 Thur)
精簡流程
developer提交代碼到某branch-->觸發(fā)Jenkins構建-->構建同時做質量檢查-->檢查通過則developer提pull request-->對request做檢查-->構建讽坏,測試成功則生成docker鏡像-->部署
CI -
當開發(fā)人員將代碼提交到其相關branch時,將觸發(fā)CI流程例证。與Git repo關聯(lián)的Git webhook將觸發(fā)Jenkins集群中的構建過程路呜。Jenkins管道用于驅動構建過程,并且存在與構建過程相關的質量關卡檢查织咧。質量門檢查應基于對共同開發(fā)部門的最低要求胀葱。在上下文中,質量門檢查可以驗證:
- 構建是否成功
- 單元測試已通過
- 沒有違反代碼風格的行為
- 新代碼的代碼覆蓋率超過80%
- Sonar掃描未報告任何漏洞或代碼氣味烦感。
CD 持續(xù)交付 -
如果質量門已經通過巡社,則開發(fā)人員可以提交其拉取請求(pull request)。集成管理器會將代碼merge到通用開發(fā)分支手趣。這將啟動通用開發(fā)分支上的構建過程晌该,如果成功,將繼續(xù)構建docker映像绿渣。
理想情況下朝群,所有測試都應作為集成過程的一部分執(zhí)行,但實際上由于測試執(zhí)行時間的原因中符,這效率很低姜胖。因此,我們將其設計為一個稱為“連續(xù)測試”的過夜時段淀散。
CT 持續(xù)測試 -
這是一個通宵的過程右莱,其中會在軟件的最新成功構建上執(zhí)行功能測試,安全掃描和性能測試等測試档插。在執(zhí)行測試之前慢蜓,將根據(jù)最新的docker鏡像將新容器部署在連續(xù)測試環(huán)境中。連接到Kubernetes集群的永久卷將作為測試的前提條件被還原郭膛。請注意晨抡,所有這些活動都是計劃的并且是完全自動化的。
第二天早上在每日站立會議之前檢查測試報告则剃。任何腳本問題將由質量保證團隊解決耘柱,而任何代碼問題將由開發(fā)團隊解決。CT故障被認為是優(yōu)先考慮的問題棍现,并將在最早的情況下得到解決调煎。
受控部署 -
由于大多數(shù)艱苦的工作已經在前面的三個步驟中完成,因此簡化了部署轴咱。成功的CT周期是唯一的資格標準汛蝙,可以在任何時候進行發(fā)布烈涮。發(fā)行腳本將
- 用相關版本號標記Docker映像
- 用版本號標記源存儲庫
現(xiàn)在,可以將發(fā)布版本部署在發(fā)布管道中的其他環(huán)境中窖剑。最終坚洽,將發(fā)行版推廣到生產將是業(yè)務決策。docker + kubernetes設置將簡化部署過程西土,并且結果在所有環(huán)境中都是可預測的讶舰。
具體流程
CI - 代碼提交 commit
代碼提交階段也稱為版本控制。提交是將開發(fā)人員編寫的最新代碼變更發(fā)送到代碼存儲庫的操作需了。開發(fā)人員編寫的代碼的每個版本都被無限期地存儲跳昼。在與合作者討論和審查變更之后,開發(fā)人員將編寫代碼肋乍,并在軟件需求鹅颊、特性增強、bug修復或變更請求完成后提交墓造。管理編輯和提交變更的存儲庫稱為源代碼管理工具(配置管理工具)堪伍。在開發(fā)人員提交代碼(代碼推送請求)后,代碼更改被合并到主線代碼分支中觅闽,這些主線代碼分支存儲在GitHub這樣的中央存儲庫中帝雇。
CI - 代碼靜態(tài)檢測 static check
開發(fā)人員編寫代碼并將其推送到存儲庫后,系統(tǒng)將自動觸發(fā)以啟動下一個代碼分析過程蛉拙。開發(fā)過程中存在這種情況:提交的代碼可以構建成功尸闸,但在部署期間構建失敗。無論從機器還是人力資源的利用率而言孕锄,這都是一個緩慢而昂貴的過程吮廉。因此必須檢查代碼中的靜態(tài)策略。SAST(靜態(tài)應用程序安全性測試):SAST是一種白盒測試方法畸肆,可以使用SonarQube茧痕,Veracode,Appscan等SAST工具從內部檢查代碼恼除,以發(fā)現(xiàn)軟件缺陷,漏洞和弱點(例如SQL注入等)曼氛。這是一個快速檢查過程豁辉,其中檢查代碼是否存在語法錯誤。盡管此階段缺少檢查運行時錯誤的功能舀患,但該功能將在以后的階段中執(zhí)行徽级。
將額外的策略檢查加入自動化流水線中可以顯著減少流程中稍后發(fā)現(xiàn)的錯誤數(shù)量。
CI - 構建 build
由開發(fā)工程師完成聊浅。
技術:Jenkins餐抢,Bamboo CI现使,Circle CI,Travis CI旷痕,Maven碳锈,Azure DevOps
流程:持續(xù)集成過程的目標是提交的代碼持續(xù)構建為二進制文件或構建產物。通過持續(xù)集成來檢查添加的新模塊是否與現(xiàn)有模塊兼容欺抗,不僅有助于更快地發(fā)現(xiàn)bug售碳,還有助于減少驗證新代碼更改的時間。構建工具可以根據(jù)幾乎所有編程語言的源代碼創(chuàng)建可執(zhí)行文件或包(.exe绞呈,.dll贸人,.jar等)。在構建過程中佃声,還可以生成SQL腳本艺智,配合基礎設施配置文件一起進行測試。簡而言之圾亏,構建階段就是編譯應用程序的階段十拣。Artifactory存儲、構建驗證測試和單元測試也可以作為構建過程的一部分召嘶。
構建驗證測試(BVT)/冒煙測試/單元測試:
創(chuàng)建構建后立即執(zhí)行冒煙測試父晶。BVT將檢查所有模塊是否正確集成,以及程序的關鍵功能是否正常運行弄跌。這樣做的目的是拒絕嚴重損壞的應用程序甲喝,以使QA團隊不會在安裝和測試軟件應用程序步驟浪費時間。
在完成這些檢查后铛只,將向流水線中執(zhí)行UT(單元測試)埠胖,以進一步減少生產中的故障。單元測試可驗證開發(fā)人員編寫的單個單元或組件是否按預期執(zhí)行淳玩。
構建產物存儲:
一旦構建就緒直撤,程序包就會存儲在稱為Artifactory或Repository工具的中央數(shù)據(jù)庫。隨著每天構建量的增加蜕着,跟蹤所有構建產物也會變得愈加困難谋竖。因此,一旦生成并驗證了構建產物承匣,就將其發(fā)送到存儲庫進行存儲管理蓖乘。諸如Jfrog Artifactory之類的存儲庫工具可用于存儲諸如.rar,.war韧骗,.exe嘉抒,Msi等之類的二進制文件。測試人員可以從此處手動進行選擇袍暴,并在測試環(huán)境中部署構建產物以進行測試些侍。
CI - 測試
參與者:測試人員隶症、QA
技術:Selenium,Appium岗宣,Jmeter蚂会,SOAP UI,Tarantula
過程:發(fā)布構建過程后的一系列自動測試將驗證代碼的準確性狈定。此階段可幫助避免生產中的錯誤颂龙。根據(jù)構建的大小,此檢查可能持續(xù)數(shù)秒至數(shù)小時纽什。對于由多個團隊提交和構建代碼的大型組織措嵌,這些檢查在并行環(huán)境中運行,以節(jié)省寶貴的時間并盡早將錯誤通知開發(fā)人員芦缰。
測試人員(或稱為QA工程師)基于用戶描述的測試用例和場景設置自動化測試用例企巢。他們執(zhí)行回歸分析、壓力測試來檢查與預期輸出的偏差让蕾。測試中涉及的活動有完整性測試浪规、集成測試、壓力測試探孝。這是一個高層次測試方法笋婿。在這個階段,可以發(fā)現(xiàn)開發(fā)人員忽視的某些代碼問題顿颅。
集成測試:
集成測試是使用Cucumber缸濒、Selenium等工具執(zhí)行的,在這些工具中粱腻,單個應用程序模塊被組合起來并作為一組進行測試庇配,同時評估其是否符合指定的功能需求。在集成測試之后绍些,需要有人批準該組中的更新集應該移到下一個階段捞慌,這通常是性能測試。這個驗證過程可能很麻煩柬批,但它是整個過程的一個重要部分啸澡。驗證這個過程業(yè)界有很多優(yōu)秀的方案。
性能和壓力測試:
Selenium氮帐、JMeter等自動化測試工具也可執(zhí)行性能和壓力測試锻霎,以檢查應用程序在面對高負載時是否穩(wěn)定和性能良好。該測試流程通常不會在每個更新提交上運行揪漩,因為完整的壓力測試是長期運行的。當發(fā)布主要的新功能時吏口,將對多個更新進行分組奄容,并完成完整的性能測試冰更。在單個更新被轉移到下一階段的情況下,流水線可能將金絲雀測試加入作為可選昂勒。
CD - 持續(xù)交付
參與者:站點可靠性工程師(SRE)蜀细、運營和維護團隊。
技術:JIRA戈盈、ServiceNow奠衔、Slack、電子郵件塘娶、Hipchat归斤。
過程:DevOps團隊的目標是更快地持續(xù)發(fā)布,然后不斷減少錯誤和性能問題刁岸。這是通過不時地通過發(fā)送電子郵件向開發(fā)人員脏里、項目經理提供有關新版本的質量和性能的反饋。通常情況下虹曙,反饋系統(tǒng)是整個軟件交付過程的一部分迫横。因此,交付中的任何更改都會頻繁地錄入系統(tǒng)酝碳,以便交付團隊可以對它采取行動矾踱。
CD - 持續(xù)部署
參與者:基礎架構工程師,SRE疏哗,運維工程師
技術:Spinnaker呛讲,Argo CD,Tekton CD
過程:在測試階段完成之后沃斤,可以部署到服務器的標準代碼準備就緒圣蝎。在部署到生產中之前,它們將被部署到產品團隊內部使用的測試環(huán)境或beta環(huán)境衡瓶。在將構建移至這些環(huán)境之前徘公,構建必須經過Bake和Deploy的子階段。這兩個階段都是Spinnaker所支持存在的哮针。
CD:Bake
Baking是指在生產時使用當前配置從源代碼創(chuàng)建不可變的鏡像實例关面。這些配置可能是數(shù)據(jù)庫更改和其他基礎結構更新之類的事情。Spinnaker可以觸發(fā)Jenkins執(zhí)行此任務十厢,并且某些組織更喜歡使用Packer等太。
CD:部署
Spinnaker自動將已bake的鏡像發(fā)送到部署階段。這是將服務器組設置為部署到集群的位置蛮放。與上述測試過程類似缩抡,在部署階段將執(zhí)行功能相同的過程。首先將部署移至測試階段包颁,然后最終移至生產環(huán)境瞻想,以進行批準和檢查压真。這個處理過程可以由Spinnaker等工具支持。
CD:驗證
這也是團隊優(yōu)化整個CI/CD流程的關鍵位置蘑险。因為現(xiàn)在已經進行了如此多的測試滴肿,所以失敗很少見。但是佃迄,此時必須盡快解決所有故障泼差,以最大程度地減少對最終客戶的影響。團隊也應該考慮使流程的這一部分自動化呵俏。
使用藍綠部署堆缘、金絲雀分析、滾動更新等策略部署到產品柴信。在部署階段套啤,將監(jiān)視正在運行的應用程序以驗證當前部署是否正確或是否需要回滾。
CD:監(jiān)控
參與者:站點可靠性工程師(SRE)随常、運營團隊
技術:Zabbix潜沦、Nagios、Prometheus绪氛、Elastic Search唆鸡、Splunk、Appdynamics枣察、Tivoli
過程:為了使軟件發(fā)行版具有故障安全性和健壯性争占,在生產環(huán)境中跟蹤發(fā)行版的運行狀況至關重要。應用程序監(jiān)視工具將跟蹤性能指標序目,例如CPU利用率和發(fā)行版延遲臂痕。日志分析器將掃描由底層中間件和操作系統(tǒng)產生的大量日志,以識別行為并跟蹤問題的根源猿涨。如果生產中出現(xiàn)任何問題握童,將通知利益相關者以確保生產環(huán)境的安全性和可靠性。此外叛赚,監(jiān)視階段可幫助組織收集有關其新軟件更改如何為收入貢獻的情報澡绩,幫助基礎設施團隊跟蹤系統(tǒng)行為趨勢并進行容量規(guī)劃。
CI/CD常用工具
- Jenkins以主從模式作為構建服務器
- Jenkins Pipelines推動CI流程
- Git Hooks通過代碼提交觸發(fā)構建
- SonarQube作為代碼質量工具俺附,或靜態(tài)檢測
- 用于自動化功能測試的機器人框架肥卡,Selenium等
- JMeter性能測試
- OWASP ZAP用于安全掃描
- docker和k8s用于部署
(2022.07.28 Thur)
CI/CD流程有哪些挑戰(zhàn)
環(huán)境限制
開發(fā)和測試團隊往往只能接入非常優(yōu)先的資源,或者共享環(huán)境用于測試代碼事镣。共享環(huán)境對CD工作流來說是個挑戰(zhàn)步鉴。在大型項目中搞监,多個團隊可能同時向同一個環(huán)境/代碼庫提交代碼的情況授账。同樣的达舒,多個測試也可能并行進行灿渴,而不同的提交和測試可能需要不同的環(huán)境配置。如果他們恰好基于同一個基礎架構(infrastructure)艺沼,情況就會更糟,配置不恰當?shù)沫h(huán)境可能導致測試和部署失敗蕴掏,并拖慢CI/CD的進程障般。
版本控制問題
一般的CI/CD流程性需要多個源、分量(component)和進程盛杰。一旦一條pipeline啟動運行挽荡,必須提供穩(wěn)定的版本運行進程。運行期間的版本變動會拖累(derail)整個pipeline并放緩部署進程即供。
DevOps團隊通扯猓花很久維護版本控制,甚至有的團隊會分配版本控制管理給特定的部門和職位逗嫡。一個最糟糕的場景是自動化的更新開啟并迫使更新作用于一個關鍵進程青自。除了打斷進程,新版本還會導致當前CI/CD流程的兼容性問題驱证。面對這類問題延窜,團隊不得不重構整個CI/CD部署流程來支持新版。
以現(xiàn)有工作流的整合
將新的CI/CD pipeline與已經存在的工作流整合相當困難抹锄。大型的遺產項目問題尤其嚴重因為對其中一個工作流的簡單修改可能迫使其他工作都做出修改逆瑞,更可能導致整體重構。
在當前項目中實現(xiàn)CI/CD需要精密計劃伙单,廣泛專業(yè)知識获高,和恰當?shù)墓ぞ摺S媱澆怀浞值膶崿F(xiàn)可能導致嚴重延時并降低服務品質吻育。
跨團隊溝通
CI/CD pipeline一般來說需要投入大量勞動力念秧,常涉及多個團隊∩ㄕ樱跨團隊溝通往往是CI/CD流程的最大障礙出爹。
案例記錄
類CI/CD案例1
在線交易平臺上有大量的rule用于預測和阻止欺詐交易或潛在的欺詐交易,通過不同的rule來實現(xiàn)缎除。一旦交易的特征滿足rule規(guī)定的條件严就,相應的rule就會工作,對交易做出各類預設的動作器罐。rule由風險分析師提交梢为,保存在IBM Decision Center系統(tǒng)上,DC是生產環(huán)境,交易都要經由DC處理铸董,以決定是否完成交易祟印。DC上的rule代碼來自業(yè)務代碼的git repo(gr)的main branch。
rule需要根據(jù)業(yè)務需求創(chuàng)建粟害、更新或刪除蕴忆。當風險分析師需要對rule做調整,到gr的main branch上提pull request悲幅。運行團隊檢查pull request中要修改的內容是否符合rule的規(guī)范套鹅,也就是static check。檢測通過汰具,則在pull request頁面生成一個臨時repo卓鹿。臨時repo被clone到本地之后,經由Eclipse的定制版打開留荔,再由Eclipse連接到DC的測試環(huán)境吟孙,并上傳。到DC的測試環(huán)境查看修改是否成功上傳聚蝶,如果成功杰妓,則rule的測試已經通過。
此時可以對pull request做merge操作既荚,使其成為main branch的一部分稚失。main branch的內容定期從DC的生產環(huán)境pull,保持生產環(huán)境的代碼為最新恰聘。
公司A的CI/CD流程
(2022.12.03 Sat)
某后端服務A用于部署到生產環(huán)境句各,對前端提供服務。開發(fā)者向A添加新feature的流程如下:
- 從服務A的
main branch
創(chuàng)建新branch晴叨,稱之為feature-a
- 將
feature-a
clone到local - 在local的
feature-a
中進行開發(fā) - 在local的
feature-a
中完成unit test - 將local的
feature-a
push到remotefeature-a
- remote線上運行提前構建的build, test等流程
- build, test等流程完成凿宾,開發(fā)者向
main branch
提出pull request(PR) - 相關開發(fā)者收到PR申請,review即將添加到
main branch
的代碼 - 相關開發(fā)者approve/reject新代碼到
main branch
中
在該過程中有如下環(huán)節(jié)需要注意
- 在開發(fā)者創(chuàng)建
feature-a
之后和提PR之前兼蕊,main branch
可能已經被其他開發(fā)者修改初厚,如圖所示
如果雙方同時修改同一個地方,會造成code conflicts孙技。這種情況下产禾,在執(zhí)行PR之前需要對feature-a
的代碼進行修改,即PR從main
到feature-a
牵啦,執(zhí)行修改亚情,重新提PR。具體流程參考本文所在文集的代碼沖突修改一文哈雏。
或考慮使用pre-commit
工具楞件。
- 在push代碼到remote之后執(zhí)行的build和test衫生,可通過Jenkins或Azure pipeline實現(xiàn)。
Refenrece
1 wikipedia - CI/CD pipeline
2 codefresh點io - what is a CI/CD pipeline a complete guide
3 知乎 - 6張圖帶你搞懂CI/CD
4 51CTO - 實施有效有價值的CI / CD流水線實踐分享