您遵循過這些Jenkins優秀實踐嗎?
譯文【51CTO.com快譯】隨著編排工具的普及,我們能夠以持續集成(CI)和持續交付(CD)的方式,實現開發與運營的無縫協作。在許多軟件開發團隊中,他們首選的DevOps自動化工具,當屬Jenkins。下面,我將和您討論在使用Jenkins的過程中,一些值得遵循的優秀實踐。
一、時刻保持Jenkins的安全
在默認配置情況下,Jenkins是不執行任何安全檢查的。也就是說,除一些簡單基本的Jenkins配置、作業和構建,網站的訪問者幾乎可以在Jenkins的主數據庫中執行任何隨機代碼。同時,Jenkins還允許在所有連接的代理上,執行包括用戶密碼、證書、以及其他隱私數據之類的代碼操作。
具體實踐
為了保護Jenkins的安全,我們需要通過如下兩個方面,來“配置全局安全性(Configure Global Security)”選項。
安全領域: 通常也被稱為“身份驗證”。它會告知Jenkins的基本環境,以及從何處提取用戶信息。
如上圖所示,從Jenkins V2.214和Jenkins LTS V2.222.1開始,“Jenkins自己的用戶數據庫”被用作了默認的安全選項。而對于兩者之前的版本,我們應當選中“啟用安全”復選框,以方便用戶使用其憑據登錄,進而避免任何侵入。
在配置有諸如LDAP之類外部身份提供者的組織中,我們需要為Jenkins實例安裝并啟用LDAP插件,以實現將所有身份驗證(包括用戶和組),都委派給已配置的LDAP服務器。
授權:告知Jenkins環境中有關哪些用戶和(或)組,可以訪問Jenkins的哪些方面,以及他們的權限。如上圖所示,我們有五種授權的選擇方式:
- 任何人都可以做任何事:除了本地測試的Jenkins控制器,我們應避免啟用該設置。畢竟所有人、包括匿名用戶都可以完全控制Jenkins,是極其危險的。
- 舊版模式:我們同樣應當避免選用該設置。只有具有“管理員”角色的用戶才能被授予對系統具有完全控制權;否則,他們將只有讀取權限。
- 已登錄的用戶可以執行任何操作:此模式會強制每個用戶在使用Jenkins之前,必須登錄。據此,匿名用戶只能獲得對于Jenkins的讀取訪問權限,或者根本就沒有訪問權限。同時,用戶的任何操作也會得到審核。
- 基于矩陣的安全性:該方案可以準確控制在Jenkins環境中,哪些用戶和組可以執行哪些操作。
- 基于項目的矩陣授權策略:該插件提供了基于矩陣的安全性,和基于項目的矩陣授權策略,因此它們需要在Jenkins上被單獨安裝。同時,該授權方案是對基于矩陣的安全性的擴展,它允許在“項目配置”的界面中,為每個項目、以及特定的用戶或組,分別定義訪問控制列表(ACL)。總的說來,此類策略為許多Jenkins環境提供了極好的安全性和靈活性,因此是一種不錯的實踐。
為了保護Jenkins用戶免受其他威脅,我們還可以按需開啟如下功能(它們默認處于關閉狀態):
- 跨站點請求偽造(CSRF)保護:防止針對運行在防火墻內部的Jenkins進行遠程攻擊。CSRF設置的路徑為:“管理Jenkins”>“配置全局安全性”>“部分:CSRF保護”。具體說明請參見--https://www.jenkins.io/doc/book/managing/security/#cross-site-request-forgery。當然,從Jenkins 2.0開始,CSRF保護是默認已啟用的。
- 在主節點上運行構建的安全隱患:在主節點上運行的構建,是可以讀取或修改JENKINS_HOME中任何文件的。由于可以讀取憑據,創建管道與作業,安裝插件,因此會影響Jenkins的整個構建過程。通常,為了配置主節點為不具備執行權限,我們既可以只在構建代理上運行構建,又可以在構建代理中,將管理Jenkins的人員與配置人員,以及提交項目的人員角色區分開來;或者直接使用“作業限制插件(Jobs Restrictions Plugin)”,來對哪些作業可以在主節點上運行進行過濾。
二、始終備份JENKINS_HOME目錄
Jenkins的主目錄包含了:作業配置、構建日志、插件配置等各種重要的數據。我們可以通過Jenkins提供的插件,來配置需要備份的作業。
具體實踐
1.精簡備份(Thin Backup)插件
這是所有提供自動化定期備份的工具中,最方便的插件之一。它的啟用過程為:
- 通過“管理Jenkins”>“管理插件”>“單擊‘可用’選項卡”>“搜索‘精簡備份’”以安裝插件。
- 完成安裝后,請轉到“管理Jenkins”>“精簡備份”>“設置”。
- 單擊“立即備份”以測試備份的效果。
2.定期備份插件
如下圖所示,一旦配置完成,該插件將會定期運行備份作業。具體內容,請參閱--https://plugins.jenkins.io/periodicbackup/。
該插件定義了如下三個方面:
- 文件管理器:定義在備份中需要包括哪些文件,以及文件的還原策略。例如,ConfigOnly將僅選擇配置類XML文件。
- 存儲:指定存檔和取消存檔備份的方法。例如,“ZipStorage”會將備份文件壓縮為ZIP檔案。
- 位置:指定備份的位置。例如,“LocalDirectory”是將備份文件存儲到指定的路徑上。
3.配置常規備份作業
- 在創建新的Jenkins任務時選擇“自由式項目”。
- 將SCM標記為“無”。
- 在“構建觸發器”中選擇“定期構建”,然后在“計劃”中配置頻率。
- 根據配置文件,添加執行殼(Execute Shell),以構建作業。
4.將Jenkins配置備份到Google Cloud存儲空間
如果您在Google Cloud的Kubernetes集群上部署了Jenkins的服務器配置,則可以將上述精簡備份插件與Google Cloud Storage插件一起使用,以便連接到云端。具體實現說明,請參照--https://medium.com/faun/backing-up-jenkins-to-google-cloud-storage-4ba12e69ded2。
三、為每個維護或開發分支,設置不同的作業/項目
眾所周知,利用持續集成工具的優勢之一便是:在開發生命周期的早期階段,能夠檢測出問題。而Jenkins恰好提供了并行構建管道的方法。因此,為每個分支設置不同的作業/項目,可以讓我們在開展并行開發的同時,盡早發現問題,降低風險,并提高開發人員的生產率。
具體實踐
最新的Parallel Test Executor插件(請參見--https://plugins.jenkins.io/parallel-test-executor/),可幫助我們執行并行測試。
四、防止并行運行的作業產生資源沖突
當然,值得注意的是,多個同時運行的作業在創建服務或需要排他式的訪問時,可能由于沖突的產生,而導致Jenkins管道失效。
具體實踐
我們可以為并行的各個項目構建,分配不同的端口,以避免沖突。例如,對于數據庫之類需要鎖定某個持久資源的需求場景,我們可以通過采用Throttle Concurrent Builds 插件(請參見--https://wiki.jenkins.io/display/JENKINS/Throttle+Concurrent+Builds+Plugin),來根據全局配置或某個項目啟用的節點數,調節并行構建的數量。
如上圖所示,我們可以使用0,將并發構建設置為無限。
五、使用“文件指紋”管理依賴項
我們在Jenkins上創建依賴項時,往往容易引發相互之間版本的混淆問題。而Jenkins支持的“文件指紋(File fingerprinting)”功能正好可以簡化該過程。
具體實踐
我們需要將所有相關項目,都配置為記錄下由項目產生的jar文件,以及項目所有依賴項的jar文件指紋。在具體配置上,您可以依次進入:“項目”>“配置”>“構建后操作”>“記錄指紋”。同時,您可以參考文檔--https://wiki.jenkins.io/display/JENKINS//Fingerprint。
六、避免在管道中使用復雜的Groovy代碼
對于Jenkins管道,Groovy代碼往往會在主服務器上調用大量的主資源(如:內存和CPU)來執行。因此,我們需要減少在管道中執行的Groovy代碼量。
具體實踐
1. JsonSlurper
此功能函數與XmlSlurper或readFile類似,可被用于從磁盤上讀取文件,將文件中的數據解析為JSON對象,然后使用JsonSlurper().parseText(readFile(“$LOCAL_FILE”))命令,將該對象注入管道中。由于該命令會兩次將本地文件加載到主服務器上的內存中,因此如果文件過大、或該命令被反復執行的話,則將消耗大量的內存。
解決方案:為了代替JsonSlurper,我們可以使用shell step的如下命令。
- def JsonReturn = sh label: ”, returnStdout: true, script: ‘echo “$LOCAL_FILE”| jq “$PARSING_QUERY”‘
它將使用代理資源來讀取文件,其中的$PARSING_QUERY將有助于將文件解析成小塊。
2. HttpRequest
通常,此命令可用于從外部資源獲取數據,并將其存儲在變量中。在此過程中,由于請求直接來自主服務器,而如果主服務器未加載證書,則可能造成HTTPS請求的結果不一致。另外,該請求的響應也會被重復性地存儲了兩次。
解決方案:使用shell step來執行代理的HTTP請求。例如,我們可以適當地使用諸如curl或wget等工具。同時,如果結果必須是在Jenkins管道的后端,那么我們則必須在代理端過濾掉盡可能多地結果,以便只把必要的信息傳送到Jenkins的主數據庫中。
七、建立可擴展的Jenkins管道
相比一般的程序庫,共享庫(Shared Libraries)提供了版本控制的管道代碼。我們可以從源代碼管理(SCM)處進行存儲和訪問。
具體實踐
我們需要在SCM中存儲具有一致性結構的源文件,然后使用SCM的插件,將該庫連接到Jenkins實例上。具體的操作步驟為:依次在“管理Jenkins”>“配置系統”>“全局管道庫”下啟用全局共享庫。當然,我們也可以在Jenkinsfile中使用庫名稱,以允許管道訪問共享庫。
八、管理聲明式語法和聲明式管道
當涉及到企業級Jenkins的實施和管道資源的管理時,我們可以通過聲明式管道配置,告知系統該如何運作,以便將復雜性轉移到系統上。同時,您可以參考通用的聲明性步驟(請參見--https://jenkins.io/doc/book/pipeline/getting-started/#directive-generator),來創建未開發的管道;或使用代碼段生成器(請參見--https://www.jenkins.io/doc/book/pipeline/getting-started/#snippet-generator),將現有的構建步驟轉換為管道語法。此外,《管道入門指南》和《管道示例》都是兩個不錯的社區參考資源。
九、保持較高的測試代碼覆蓋率,并將單元測試作為管道的一部分
顯然,代碼測試的覆蓋率越高,產品的缺陷就會越少,用戶驗收測試(UAT)的通過率也就越高。因此,我們需要依靠更詳細的單元測試,以及更高的測試覆蓋范圍,來確保開發人員在開發生命周期的早期階段,提高代碼的質量。
具體實踐
1. Jenkins Cobertura插件
為了捕獲代碼覆蓋率的相關報告,我們需要完成Cobertura插件的如下配置步驟:
- 通過“管理Jenkins”>“管理插件”來安裝Cobertura插件。
- 配置項目的構建腳本,以生成Cobertura XML報告。
- 啟用“發布Cobertura覆蓋率報告”。
- 指定生成coverage.xml報告的目錄。
- (可選)配置覆蓋率的相關指標。
您可以通過鏈接,來獲悉如何配置單個項目、項目的層次結構、以及Maven。
2.代碼覆蓋率API插件
作為統一的API插件,它能夠支持Cobertura等其他插件。其主要功能包括:
- 根據用戶的配置,查找覆蓋率的相關報告。
- 使用適配器將報告轉換為標準格式。
- 匯總已解析的標準格式化報告,并在圖表中顯示已解析的結果。
3.LambdaTest Selenium Grid Cloud
由于提供了廣泛的瀏覽器及其版本庫,因此您可以在使用Selenium測試套件,在執行自動化測試時,獲得更高的測試覆蓋率。通常,LambdaTest Jenkins插件可以提供:
- 為Jenkins作業配置LambdaTest憑據。
- 設置Lambda隧道并刪除二進制文件,以方便在本地托管的Web應用上,進行自動化跨瀏覽器測試。
- 將包括視頻日志、網絡日志、以及LambdaTest執行步驟的相關截圖等所有測試結果,嵌入Jenkins的作業結果。
在完成LambdaTest Jenkins插件的安裝后,我們通過將Jenkins CI實例連接到LambdaTest grid上,來自動化Selenium自動化測試腳本。您也可以通過鏈接,參考Jenkins集成的支持文檔。
十、監控CI/CD管道
我們需要通過監控,來獲悉諸如云服務、網絡、測試服務等外部依賴項是如何影響CI/CD管道的,以便及時采取行動。在此,我們可以使用Jenkins Slack插件,將錯誤通知發送到由值守工程師監控的頻道中。該插件不但可以提供諸如:構建合格率、平均構建時間、以及特定階段的錯誤計數等信息;還能夠協助我們識別出在構建中,效率低下、需要改進的潛在區域。
小結
總的說來,Jenkins的優秀實踐包括:讓Jenkins運行在自己的用戶數據庫上,采用基于權限和用戶矩陣的訪問控制方式,自動運行相關配置的備份,鼓勵應用團隊采用Shell step,以避免復雜的Groovy腳本,擁有共享庫和Jenkinsfiles的所有權,通過使用自動化狀態插件來監控管道,并定義聲明性的管道,提高代碼測試的覆蓋率,以及讓代碼覆蓋率API與LambdaTest Selenium Grid相集成,以實現無缺陷的交付。
原文標題:Are You Following These Jenkins Best Practices?,作者: Kritika Murari
【51CTO譯稿,合作站點轉載請注明原文譯者和出處為51CTO.com】