Jenkins部署Python项目实战
一、背景
我們工作中常用Jenkins部署Java代碼,因其靈活的插件特性,例如jdk,maven,ant等使得java項目編譯后上線部署一氣呵成,同樣對于腳本語言類型如Python上線部署,利用Jenkins強大的插件功能,輕松實現CI/CD,但如果部署多項目到同一臺服務器涉及環境一致性問題,對此可以利用容器技術Docker解決,也可以利用Python虛擬環境例如virutalenv或conda等優秀等工具解決,在此由于后期根據requirements來安裝依賴包比較慢,且后期需要將Python整個環境打包,利用conda工具來對項目環境進行管理,方便快速移植。
本文較系統的記錄下部署一個具體的Django項目,包括利用conda工具來實現Python多環境管理,Pylint工具來實現代碼檢查,使用nose框架做單元測試和覆蓋率。
二、必備知識
- Jenkins基礎安裝部署
可參考:https://blog.51cto.com/kaliarch/2050862
- Conda軟件包管理系統
由于conda包較大,通常情況下可以使用Miniconda
官網下載地址:https://conda.io/en/latest/miniconda.html
基礎使用命令:
- conda env export > environment.yaml
同樣,當執行他人的代碼時,也需要配置相應的環境。這時你可以用對方分享的 YAML 文件來創建一摸一樣的運行環境
conda env create -f environment.yaml
Shell基礎
可參考:https://myshell-note.readthedocs.io/en/latest/index.html
- GIT基礎
可參考:https://blog.51cto.com/kaliarch/2049724
三、優化
- 生成主題
主題工具生成鏈接:http://afonsof.com/jenkins-material-theme/
在主題工具生成喜歡的顏色已經上傳logo下載生成的主題到Jenkins服務器的jenkins 家目錄,一般為安裝啟動jenkins系統用戶的家目錄下.jenkins/userContent/material/,如果沒有此目錄需要新建目錄,css文件移動到目錄下,例如/root/.jenkins/userContent/material/blue.css。
- Jenkins上配置主題
a.Install?Jenkins Simple Theme Plugin
b.點擊Manage Jenkins
c.點擊Configure System
d.找到 Theme 配置
e.填寫本地主題cssurl,例如:http://localhost:8080/jenkins/userContent/material/blue.css
f.Click Save
g.保存可查看效果。
- 注意
本地css的url可以瀏覽器打開測試訪問,如果訪問不到會默認加載Jenkins默認主題
后期遷移url最好寫成localhost,如果寫公網IP,css文件不存在404,Jenkins頁面會很卡。
四、部署實戰
4.1 服務器列表
| Jenkins-server | 10.57.61.138 | miniconda | Jenkins服務器 |
| Des-server | 172.21.0.10 | miniconda | 項目部署服務器 |
4.2 架構圖
4.3 前期準備
- pylint: Python靜態代碼審查包,參考:http://pylint.pycqa.org/en/latest/user_guide/run.html
- mock: 用來生成測試數據。
- nose: Python單元測試包。
- coverage: Python代碼覆蓋率包。
對依賴包需要在Jenkins-server服務器進行安裝,首先根據項目里面conda創建對應項目對虛擬環境conda create -n <project_name> python=3.6,創建完成利用conda env list查看環境,為避免環境污染,在項目環境內利用pip工具安裝軟件pip install pylint mock nose coverage。
- JUnit: 用來展示nose框架生成的單元測試報表(Allows JUnit-format test results to be published.)
- Cobertura Plugin:用來展示Python代碼測試覆蓋率報表(This plugin integrates Cobertura coverage reports to Jenkins.)
- Violations plugin:用來展示Python靜態代碼審查報表(This plugin does reports on checkstyle, csslint, pmd, cpd, fxcop, pylint, jcReport, findbugs, and perlcritic violations.),參考:https://wiki.jenkins.io/display/JENKINS/Violations
- Git Plugin:用來從Gitbucket源代碼庫拉取代碼(This plugin allows GitLab to trigger Jenkins builds and display their results in the GitLab UI.)
- Git Parameter:用于參數化構建選擇git的branch(Adds ability to choose branches, tags or revisions from git repositories configured in project.)
4.4 創建任務
- 創建自由風格軟件項目
New任務->構建一個自由風格的軟件項目,填寫描述,在此由于后期會利用pylint進行代碼檢查,給出了代碼檢查的消息類型,可以根據消息類型進行相應修復處理。
- 配置參數化構建
配置選擇git具體branch進行構建,和可以自定義端口,在此需要注意參數化構建的變了Name,在后續需要用到。
- 源碼管理
在此需要選擇源碼倉庫,選擇gitlab已經認證方式,需要注意由于參數化構建選擇了branch,在Branches to build需要引用上面的變量$branch。
- 構建配置
- 執行shell
執行shell此shell為在Jenkins服務器上執行,所以需要預先在其上配置Python虛擬環境,在其上進行代碼審查,單元測試生成nosetests.xml文件,已經代碼覆蓋率測試生成coverage.xml文件,pylint測試生成pylint.xml文件。
以下為此項目示例shell腳本,此腳本需要根據自己的實際情況來修改,需要注意Python項目結構與需要代碼檢查的標識符。
base_dir=/root/.jenkins/workspace/ project=go2cloud-api-deploy-prod/ project_env=go2cloud-api-env # 切換python環境 source activate ${project_env} $(which python) -m pip install mock nose coverage # 更新python環境 echo "+++更新Python環境+++"if [ -f ${base_dir}${project}requirements.txt ];then$(which python) -m pip install -r ${base_dir}${project}requirements.txt && echo 0 || echo 0 fi# 代碼檢查/單元測試/代碼測試覆蓋率 echo "+++代碼檢查+++" cd ${base_dir} # 生成pylint.xml $(which pylint) -f parseable --disable=C0103,E0401,C0302 $(find ${project}/* -name *.py) >${base_dir}pylint.xml || echo 0echo "+++單元測試+++" # 生成nosetests.xml #$(which nosetests) --with-xunit --all-modules --traverse-namespace --with-coverage --cover-package=go2cloud-api-deploy-prod --cover-inclusive || echo 0 $(which nosetests) --with-xunit --all-modules --traverse-namespace --with-coverage --py3where=go2cloud-api-deploy-prod --cover-package=go2cloud-api-deploy-prod --cover-inclusive || echo 0 echo "+++代碼覆蓋率+++" # 生成coverage.xmlpython -m coverage xml --include=go2cloud-api-deploy-prod* || echo 0
- 發送文件及命令到目標服務器
在此需要制定發布到目標到的服務器遠端目錄,已經執行的命令,在此執行重啟腳本。
由于在此項目為Django項目,需要制定虛擬環境/入口啟動文件/啟動端口。
將之前參數化構建的端口當作變量傳遞給腳本,啟動相應的端口
- 構建后動作
- JUnit插件實現單元測試報告,需要指定nosetests.xml
- Cobertura Plugin插件實現覆蓋率測試
- Violations插件進行代碼審計,需要制定Jenkins-server上的生成的pylint.xml文件。
需要注意文件路徑為jenkins服務器pylint.xml,以及對應生成文件的編碼。
- 郵件通知配置
選擇郵件內容為Content Type為HTML,這樣可以編寫郵件HTML模版,生成較為好看的郵件通知模版。
注意選擇觸發告警可以選擇類型,失敗幾次或無論構建成功失敗都發送,可根據具體需求配置。
郵件HTML模版
<td><a href="http://www.yxccc.com" target="_blank">電動叉車</a></td><td><b><font color="#0B610B">Changes Since LastSuccessful Build:</font></b><hr size="2" width="100%" align="center" /></td></tr><tr><td><ul><li>歷史變更記錄 : <a href="${PROJECT_URL}changes">${PROJECT_URL}changes</a></li></ul> ${CHANGES_SINCE_LAST_SUCCESS,reverse=true, format="Changes for Build #%n:<br />%c<br />",showPaths=true,changesFormat="<pre>[%a]<br />%m</pre>",pathFormat=" %p"}</td></tr><tr><td><b>Failed Test Results</b><hr size="2" width="100%" align="center" /></td></tr><tr><td><prestyle="font-size: 11pt; font-family: Tahoma, Arial, Helvetica, sans-serif">$FAILED_TESTS</pre><br /></td></tr><tr><td><b><font color="#0B610B">構建日志 (最后 100行):</font></b><hr size="2" width="100%" align="center" /></td></tr><!-- <tr><td>Test Logs (if test has ran): <ahref="${PROJECT_URL}ws/TestResult/archive_logs/Log-Build-${BUILD_NUMBER}.zip">${PROJECT_URL}/ws/TestResult/archive_logs/Log-Build-${BUILD_NUMBER}.zip</a><br /><br /></td></tr> --><tr><td><textarea cols="80" rows="30" readonly="readonly"style="font-family: Courier New">${BUILD_LOG, maxLines=100}</textarea></td></tr></table> </body> </html>
4.5 進行構建測試
- 觸發構建
選擇對應的branch與端口
- 查看consle log
- pylint檢查
- nosetests單元測試及代碼覆蓋率
- 目標服務器查看具體項目
4.6 查看構結果
- 總覽查看
- 查看代碼覆蓋率
查看具體不合規代碼
在源代碼分析結束后面,會有一系列的報告,每個報告關注于項目的某些方面,如每種類別的 message 的數目,模塊的依賴關系等等。具體來說,報告中會包含如下的方面:
MESSAGE_TYPE 有如下幾種:
- 查看郵件
五、流水線部署
5.1 pipeline基礎概念
- pipeline是什么
pipeline為運行于Jenkins上的工作流框架,project中的配置信息以steps的方式放在一個腳本里將原本獨立運行于單個或者多個節點的任務連接起來,實現單個任務難以完成的復雜流程編排與可視化。
- 基礎概念
- Stage: 階段:告訴Jenkins做什么,一個Pipeline可以劃分為若干個Stage,每個Stage代表一組操作。注意,Stage是一個邏輯分組的概念,可以跨多個Node。
- Node: 節點:告訴Jenkins在job在哪運行一個Node就是一個Jenkins節點,或者是Master,或者是slave,是執行Step的具體運行期環境。
- Step: 步驟:具體細化到每一步構建操作,Step是最基本的操作單元,小到創建一個目錄,大到構建一個Docker鏡像,由各類Jenkins Plugin提供。
- 語發工具
Pipeline提供了一組可擴展的工具,通過Pipeline Domain Specific Language(DSL)syntax可以達到Pipeline as Code(Jenkinsfile存儲在項目的源代碼庫)的目的。
參考:https://wiki.jenkins.io/display/JENKINS/Pipeline+Plugin
5.2 pipeline的特性
基于 Jenkins Pipeline,用戶可以在一個 JenkinsFile 中快速實現一個項目的從構建、測試以到發布的完整流程,并且可以保存這個流水線的定義。
- 代碼:Pipeline以代碼的形式實現,通常被檢入源代碼控制,使團隊能夠編輯、審查和迭代其CD流程。
- 可持續性:Jenklins重啟或者中斷后都不會影響Pipeline Job。
- 停頓:Pipeline可以選擇停止并等待任工輸入或批準,然后再繼續Pipeline運行。
- 多功能:Pipeline支持現實世界的復雜CD要求,包括fork/join子進程,循環和并行執行工作的能力
- 可擴展:Pipeline插件支持其DSL的自定義擴展以及與其他插件集成的多個選項。
5.3 pipeline語法
- 聲明式
在聲明式流水線中有效的基本語句和表達式遵循與?Groovy的語法同樣的規則, 有以下例外:
- 流水線頂層必須是一個?block, 特別地: pipeline { }
- 沒有分號作為語句分隔符,,每條語句都必須在自己的行上。
- 塊只能由?節段,?指令,?步驟, 或賦值語句組成。 *屬性引用語句被視為無參方法調用。 例如, input被視為 input()
示例:
Jenkinsfile (Declarative Pipeline) pipeline {agent none stages {stage('Example Build') {agent { docker 'maven:3-alpine' } steps {echo 'Hello, Maven'sh 'mvn --version'}}stage('Example Test') {agent { docker 'openjdk:8-jre' } steps {echo 'Hello, JDK'sh 'java -version'}}} }詳細學習可參考:https://jenkins.io/zh/doc/book/pipeline/syntax/
- 腳本式
腳本化流水線, 與[declarative-pipeline]一樣的是, 是建立在底層流水線的子系統上的與聲明式不同的是, 腳本化流水線實際上是由?Groovy構建的通用 DSL [2]。 Groovy 語言提供的大部分功能都可以用于腳本化流水線的用戶。這意味著它是一個非常有表現力和靈活的工具,可以通過它編寫持續交付流水線。
示例:
node('master') { //master節點運行,以下stage也可指定節點stage 'Prepare' //清空發布目錄bat '''if exist D:\\publish\\LoginServiceCore (rd/s/q D:\\publish\\LoginServiceCore)if exist C:\\Users\\Administrator\\.nuget (rd/s/q C:\\Users\\Administrator\\.nuget)exit'''//拉取git代碼倉庫stage 'Checkout'checkout([$class: 'GitSCM', branches: [[name: '*/master']], doGenerateSubmoduleConfigurations: false, extensions: [], submoduleCfg: [], userRemoteConfigs: [[credentialsId: 'c6d98bbd-5cfb-4e26-aa56-f70b054b350d', url: 'http://xxx/xxx/xxx']]])//構建stage 'Build'bat '''cd "D:\\Program Files (x86)\\Jenkins\\workspace\\LoginServiceCore\\LoginApi.Hosting.Web"dotnet restoredotnet builddotnet publish --configuration Release --output D:\\publish\\LoginServiceCore'''//部署stage 'Deploy'bat '''cd D:\\PipelineScript\\LoginServiceCorepython LoginServiceCore.py'''//自動化測試(python代碼實現) stage 'Test'bat'''cd D:\\PipelineScript\\LoginServiceCorepython LoginServiceCoreApitest.py''' }5.4 示例
在此將上面的項目利用pipeline進行發布
- 創建自由風格軟件項目
New任務->流水線,填寫任務描述。
- Pipeline
如果對Pipeline語法不熟悉,可以利用工具生成
在此的pipeline
- 運行構建
- 查看結果
六、注意要點
- 在部署前一定梳理好流程,需要理解哪一步在目標服務器還上在Jenkins服務器上執行
- 需要對應好目錄及Python虛擬環境,避免環境污染
七、反思
- 在此利用來Conda虛擬環境管理,來在同一個服務器上解決環境不一致行,也可以利用Docker來解決
- 利用Pipeline項目發布可視化,明確階段,方便stage查看與排錯,Jenkinsfile可放在git倉庫進行
轉載于:https://www.cnblogs.com/xyou/p/10674774.html
總結
以上是生活随笔為你收集整理的Jenkins部署Python项目实战的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 【机器学习基础】--感知机完全解读
- 下一篇: java B2B2C 源码多租户电子商城