<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          持續(xù)集成和交付流水線的8個反模式 | IDCF

          共 5003字,需瀏覽 11分鐘

           ·

          2021-08-10 22:16

          來源:Thoughtworks洞見
          作者:馮煒
          原文發(fā)表:原文發(fā)表于:https://www.rea-group.com/blog/continuous-integration-and-delivery-pipeline-mistakes/


          一、CI/CD & Pipeline



          隨著DevOps的理念在眾多公司的采納,CI/CD也漸漸落地。

          • CI(Continuous Integration)持續(xù)集成,是把代碼變更自動集成到主干的一種實踐。CI的出現(xiàn)解決了集成地獄的問題,讓產(chǎn)品可以快速迭代,同時還能保持高質(zhì)量。它的核心措施是,代碼集成到主干之前,必須通過一系列自動化測試,比如編譯、單元測試、lint、代碼風(fēng)格檢查。
          • CD包括持續(xù)交付和持續(xù)部署。持續(xù)交付(Continuous Delivery)指的是團(tuán)隊自動地、頻繁地、可預(yù)測地交付高質(zhì)量軟件版本的過程,可以看做持續(xù)集成的下一個階段,強(qiáng)調(diào)的是無論代碼怎么更新,軟件都是隨時可以交付的;持續(xù)部署(continuous deployment)更強(qiáng)調(diào)的是使用自動化測試來保證變更的正確性和穩(wěn)定性,以便在測試通過后立即部署,是持續(xù)交付的更進(jìn)一步。二者的區(qū)別是,持續(xù)交付需要人為介入,需要確??梢圆渴鸬缴a(chǎn)環(huán)境時,才去進(jìn)行部署。
          圖1 持續(xù)集成 & 持續(xù)交付 & 持續(xù)部署
          CI/CD Pipeline是軟件開發(fā)過程中避免浪費的一種實踐,展現(xiàn)了從代碼提交、構(gòu)建、部署、測試到發(fā)布的整個過程,為團(tuán)隊提供可視化和及時反饋。Pipeline推薦的實施方式是,把軟件部署的過程分為不同的階段(Stage),其中任務(wù)(Step)在每個階段中運行。
          在同一階段,可以并行執(zhí)行任務(wù),幫助快速反饋,只有一個階段中所有任務(wù)都通過時,下一階段的任務(wù)才可以啟動。比如圖中,從git push到deploy to production的整個流程,就是一條CD Pipeline。可以利用Pipeline工具,如Jenkins、Buildkite、Bamboo,來幫助我們更方便的實施CI/CD。
          圖2 CI/CD Pipeline

          二、CI/CD Pipeline的反模式



          雖然有Pipeline廣泛的應(yīng)用,但我們卻會聽見開發(fā)人員抱怨糟糕的Pipeline對他們的傷害,如阻塞開發(fā)流程,影響變更的部署效率,降低交付質(zhì)量。我們收集了項目上經(jīng)常出現(xiàn)的Pipeline的八大反模式,按照出現(xiàn)頻率排序,分別闡述這些壞味道,分析可能產(chǎn)生的原因、影響及解決方式,希望能夠減少抱怨,讓Pipeline更大程度上提升工作效率。
          2.1 沒有代碼化
          反模式
          Pipeline的定義沒有完全代碼化,進(jìn)行版本控制,存儲在代碼倉庫,而是在Pipeline 工具上直接輸入shell腳本定義Pipeline的運行過程。
          原因
          由于早期的CI工具不支持代碼化,一直能夠保留到現(xiàn)在,沒有做重構(gòu)和升級。 
          影響
          Pipeline的創(chuàng)建和管理都是通過CI工具的界面交互來的,難以維護(hù),因此需要專門的管理員來維護(hù),而有人工操作的部分就會出錯,因此會降低Pipeline的可靠性。如果Pipeline因為一些原因丟失就沒有辦法很快恢復(fù),就會影響交付速率。
          解決方案
          Pipeline as code這個理念已經(jīng)提了很多年了,在ThoughtWorks 2016年的技術(shù)雷達(dá)里就已經(jīng)采納了,需要強(qiáng)調(diào)的是,用于構(gòu)建、測試和部署我們應(yīng)用程序或基礎(chǔ)設(shè)施的交付Pipeline的配置,都應(yīng)以代碼形式展現(xiàn)。隨著組織逐漸演變?yōu)闃?gòu)建微服務(wù)或微前端的去中心化自治團(tuán)隊,人們越來越需要以代碼形式管理Pipeline這種工程實踐,來保證組織內(nèi)部構(gòu)建和部署軟件的一致性。
          通常,針對某個項目的Pipeline配置,應(yīng)和項目代碼放在項目的源碼管理倉庫中。同業(yè)務(wù)代碼一樣要做code review。這種需求使得業(yè)界出現(xiàn)了很多支持Pipeline工具,它們可以以標(biāo)準(zhǔn)的方式構(gòu)建、部署服務(wù)和應(yīng)用,如Jenkins、Buildkite、Bamboo。這些工具用大多有一個Pipeline的藍(lán)圖,來執(zhí)行一個交付生命周期中不同階段的任務(wù),如構(gòu)建、測試和部署,而不用關(guān)心實現(xiàn)細(xì)節(jié)。以代碼形式來完成構(gòu)建、測試和部署流水線的能力,應(yīng)該成為選擇CI/CD工具的評估標(biāo)準(zhǔn)之一。
          2.2 運行速度慢
          反模式
          一條Pipeline的執(zhí)行時間超過半小時,就屬于運行速度慢的Pipeline。(這里的運行速度與交付的產(chǎn)品有關(guān),在不同的項目中,運行時長的限定也有所不同)
          原因
          很多原因都會導(dǎo)致運行一次Pipeline時間很長,比如:
          • 該并行的任務(wù)沒有并行執(zhí)行,等待的任務(wù)拉長了執(zhí)行時間;
          • 執(zhí)行Pipeline的agent節(jié)點太少,或者性能不足,導(dǎo)致排隊時間太長,效率太低;
          • 執(zhí)行的任務(wù)太重,相同測試場景被不同的測試覆蓋了很多次。比如同樣的邏輯在不同測試中都測了一遍;
          • 沒有合理利用緩存,比如每個任務(wù)里都要下載全部依賴,在構(gòu)建Dockerfile時沒有合理利用layer,每次都會構(gòu)建一個全新的image。
          影響
          這是開發(fā)人員抱怨最多的一個反模式。敏捷開發(fā)模式需要Pipeline快速反饋結(jié)果,受這一反模式制約,在特性開發(fā)過程中,經(jīng)常出現(xiàn)開發(fā)人員改一行代碼,等半天CI的效果。如果出現(xiàn)一個線上事故需要修改一行代碼來修復(fù),最終需要很長的周期才能讓這一更改應(yīng)用在生產(chǎn)環(huán)境。
          解決
          不同的原因?qū)е碌腜ipeline速度慢,有不同的解決方法。比如針對上面的問題,我們可以去:
          • 檢查Pipeline的設(shè)計是否合理,盡可能讓任務(wù)并行;
          • 對代碼的各種測試深入了解,讓測試盡量正交,避免過多的重復(fù);
          • 檢查代碼中的依賴,合理利用好緩存。包括Docker Image、Gradle、Yarn、Rubygem的緩存,以及Dockerfile是否合理的設(shè)計,最大化的將不可變的layer集中的開始階段;
          • 檢查執(zhí)行構(gòu)建的節(jié)點資源是否充足,能否在任務(wù)量大時做彈性伸縮,減少等待和執(zhí)行時間。
          2.3 執(zhí)行結(jié)果不穩(wěn)定
          圖3 執(zhí)行多次結(jié)果不穩(wěn)定
          反模式
          構(gòu)建相同代碼的Pipeline運行多次,得到結(jié)果不同。比如,基于同一代碼基線,一條Pipeline構(gòu)建了5次,只有最后一次通過了。
          原因
          出現(xiàn)執(zhí)行結(jié)果不穩(wěn)定的原因也多種多樣,比如測試用例的實現(xiàn)不合理,導(dǎo)致測試結(jié)果時過時不過;代碼中使用了不可靠的依賴源,比如來自國外的依賴源,下載依賴經(jīng)常超時;由或是在Pipeline運行過程中沒有合理設(shè)計各個階段,導(dǎo)致有些任務(wù)同時運行沖突了。
          影響
          Pipeline作為代碼發(fā)布的最后一道防火墻,最基本的特性是冪等性,即在一個相同的代碼基線,執(zhí)行Pipeline的任意任務(wù),不管是10次、100次,得到的結(jié)果都相同。Pipeline不穩(wěn)定會直接導(dǎo)致代碼的部署速率降低。更重要的是,影響開發(fā)人員對Pipeline的信任。如果不穩(wěn)定Pipeline不及時解決,慢慢這條Pipeline會失去維護(hù),開發(fā)最后會轉(zhuǎn)向手工部署。
          解決
          要構(gòu)建冪等的、可靠的Pipeline,就要分析這些不穩(wěn)定因素出現(xiàn)的原因。
          • 提升測試的穩(wěn)定性,比如用mock替代不穩(wěn)定的源。
          • 采用Pipeline的重試功能,或者采用穩(wěn)定的鏡像源,或者提前構(gòu)建好基礎(chǔ)鏡像。
          • 引入Pipeline的插件保證任務(wù)不會并行執(zhí)行。
          2.4 濫用job處理生產(chǎn)環(huán)境數(shù)據(jù)
          反模式
          使用Pipeline的定時任務(wù)的特性,運行生產(chǎn)環(huán)境的負(fù)載。比如經(jīng)常會定期做數(shù)據(jù)備份、數(shù)據(jù)遷移,數(shù)據(jù)抓取。
          原因
          由于對Pipeline的認(rèn)識不夠清晰,將重要的任務(wù)交由Pipeline做。Pipeline一旦有了某個生產(chǎn)環(huán)境的訪問權(quán)限,做這些數(shù)據(jù)處理相關(guān)的任務(wù)就很方便,減少了很多人為的操作。
          影響
          Pipeline是用來做構(gòu)建、部署的工具,不能用于業(yè)務(wù)邏輯的執(zhí)行。由于Pipeline是一個內(nèi)部服務(wù),他的SLO/SLI必定和生產(chǎn)環(huán)境不同,如果強(qiáng)依賴勢必影響生產(chǎn)環(huán)境的SLO。假如某天Pipeline掛掉了,生產(chǎn)環(huán)境就無法得到想要的數(shù)據(jù)。另外,任務(wù)和Pipeline緊密耦合,是我們后面會討論的另一個反模式。
          解決方法
          用生產(chǎn)環(huán)境自身的工具解決這種數(shù)據(jù)問題,比如 采用AWS的lambda,定時觸發(fā)數(shù)據(jù)處理任務(wù)。
          2.5 復(fù)雜難懂
          圖4 Pipeline的定義邏輯復(fù)雜
          反模式
          Pipeline的定義包含了太多的邏輯,復(fù)雜難懂。只有在一條Pipeline運行起來才能知道這里會運行哪些步驟,會將這個版本部署到哪些環(huán)境。
          原因
          Pipeline的代碼不夠整潔。有人認(rèn)為Pipeline只是給CI工具提供的,就隨意編寫,認(rèn)為能完成指定的工作就夠了。
          影響
          Pipeline的復(fù)雜性,會直接提升學(xué)習(xí)成本。如果想重復(fù)執(zhí)行上一次構(gòu)建,會花費較長時間。
          解決
          Pipeline的代碼要簡潔,把復(fù)雜性放在部署腳本或代碼側(cè)。通過每個階段的的標(biāo)題可以直接了解所要執(zhí)行的任務(wù)。如果存在很多相同的邏輯,可以通過開發(fā)Pipeline的Plugin來簡化配置。
          2.6 耦合太高
          圖5 (左)耦合太高的Pipeline定義 (右)期待的Pipeline定義
          反模式
          Pipeline跟運行它的CI工具緊密耦合,以至于無法在本地重復(fù)相同的步驟。表現(xiàn)可能多種多樣:
          • Pipeline的定義跟構(gòu)建工具緊密耦合,包含了Pipeline工具特有的參數(shù)以及CLI命令。比如在配置中使用BUILDKITE_BUILD_NUMBER,BUILDKITE_QUEUE等等。結(jié)果就是本地運行的方式或結(jié)果和Pipeline上運行的方式以及結(jié)果不一致。
          • 在Pipeline的任務(wù)中寫了一大段腳本,或者直接使用命令加上一堆參數(shù),以至于在本地想跑測試需要在Pipeline的配置中找命令并且在本地粘貼。
          • 不做環(huán)境隔離, 測試,編譯,部署等都依賴于運行時環(huán)境??赡艹霈F(xiàn)Pipeline 因依賴的軟件/庫等版本不一致而導(dǎo)致的不一致的情況,通常還很難排查。
          影響
          因為本地不方便調(diào)試,所變更的失敗概率會大大增加。如果變更用來修復(fù)一個Bug,由于不做環(huán)境隔離,會導(dǎo)致故障修復(fù)周期拉長。
          解決
          Pipeline的每個step都用腳本封裝起來,腳本里不使用Pipeline工具特有的參數(shù),并且保證本地運行時和Pipeline上保持一致。
          2.7 僵尸Pipeline
          反模式
          一條Pipeline年久失修,很久沒有執(zhí)行過,而且最后一次的構(gòu)建是失敗的。
          原因
          這種反模式通常出現(xiàn)于不再活躍開發(fā)的項目上,因此很久沒有執(zhí)行過Pipeline。
          影響
          Pipeline的結(jié)果反應(yīng)的是一個項目的狀態(tài)。由于軟件產(chǎn)品迭代速度快,這個軟件的依賴可能已經(jīng)發(fā)生了巨大的變化,一旦運行,大概率會出錯。假如這個項目目前出現(xiàn)了一個事故,需要提交代碼,就得先修復(fù)項目的Pipeline,才能確保提交修復(fù)代碼。
          解決
          針對常年沒有提交的Pipeline,我們建議讓Pipeline周期的執(zhí)行,出現(xiàn)問題立即修復(fù)。如Github的Dependabot,能保證項目的依賴始終是是最新的,而且能讓Pipeline執(zhí)行,提早發(fā)現(xiàn)問題。
          2.8 需要人工介入
          反模式
          通常項目上會有一個專職Ops,在項目可以發(fā)布的時候手動觸發(fā)部署流程,或者需要傳遞很多參數(shù),讓Pipeline運行起來。
          原因
          包括項目的流程繁瑣,需要反復(fù)確認(rèn);DevOps成熟度不夠,沒有實現(xiàn)持續(xù)部署;或者CI的測試覆蓋不夠,CI通過后還要進(jìn)行更多的測試才能部署。
          影響
          這些Pipeline需要專人盯著,去點某些按鈕。會直接影響產(chǎn)品的交付速率和代碼部署頻率。
          解決
          讓項目的運行更加敏捷,減少Pipeline定義中的阻塞按鈕,將手工測試自動化后集成到Pipeline中。

          最后



          希望通過本篇文章,意識到項目中CI/CD Pipeline的問題,使其發(fā)揮更大的價值。
          IDCF DevOps黑客馬拉松,獨創(chuàng)端到端DevOps體驗,精益創(chuàng)業(yè)+敏捷開發(fā)+DevOps流水線的完美結(jié)合,2021年僅有的3場公開課,數(shù)千人參與并一致五星推薦的金牌訓(xùn)練營,追求卓越的你一定不能錯過!
          9月11-12日,上海站,企業(yè)組隊參賽&個人參賽均可,一年等一回,錯過等一年,趕緊上車~??
          瀏覽 59
          點贊
          評論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報
          評論
          圖片
          表情
          推薦
          點贊
          評論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  韩国女主播操逼 | 草福利| 最新爱爱视频网站 | 日本激情视频小说 | 国产丝袜足交在线观看 |