第1章 CI/CD介紹
1.什么是持續集成/持續部署
持續集成(Continuous integration)是一種軟件開發實踐,即團隊開發成員經常集成它們的工作,通過每個成員 每天至少集成一次,也就意味着每天可能會發生多次集成。每次集成都通過自動化的構建(包括編譯,發布,自動 化測試)來驗證,從而盡早地發現集成錯誤。
持續部署(continuous deployment)是通過自動化的構建、測試和部署循環來快速交付高質量的產品。某種程度 上代表了一個開發團隊工程化的程度,畢竟快速運轉的互聯網公司人力成本會高於機器,投資機器優化開發流程化 相對也提高了人的效率。
持續交付 Continuous Delivery:頻繁地將軟件的新版本,交付給質量團隊或者用戶,以供評審盡早發現生產環境 中存在的問題;如果評審通過,代碼就進入生產階段
第2章 Jenkins pipeline
1.什么是pipeline
簡單來說,就是將多個任務連接起來,組成流水線
2.pipeline概念
Agent 節點
Stage 階段
Steps 動作
3.Jenkins語法介紹
pipeline { #所有代碼都在pipeline{}內
agent any #agent{}定義任務運行在哪台主機上,可以是any,node等
environment { #定義環境變量,變量名稱=變量值,比如PATH路徑等
host='oldya.com'
}
stages { #一個項目的集合,主要用來包含所有stage子項目
stage('code'){ #一個項目中的單個任務,主要用來包含step
steps { #steps主要用來實現具體執行的動作
echo "code for host $host"
}
}
}
stage('build'){
steps {
sh "echo $host"
}
}
}
第3章 體驗pipeline項目
1.創建流水線項目

2.填寫代碼
代碼如下:
pipeline{
agent any
stages{
stage("下載代碼"){
steps{
echo "get code OK"
}
}
stage("編譯代碼"){
steps{
echo "packge code OK"
}
}
stage("部署代碼"){
steps{
echo "deploy code OK"
}
}
}
}
執行效果:

3.執行效果

第4章 SCM形式執行pipeline代碼
除了在流水線項目里直接配置pipeline代碼外,我們還可以將pipeline代碼保存成文件存放在代碼倉庫里,然后配置jenkins直接從代碼倉庫拉取pipeline file並執行流水線作業.下面我們演示一下。
1.在gitlab上創建新項目

2.填寫項目信息

3.編寫Jenkins file


4.配置部署密鑰

5.jenkins配置pipeline從gitlab拉取

6.構建測試

第4章 pipeline改造h5項目
1.創建pipeline項目

2.jenkins生成拉取代碼的pipeline語法


3.編寫pipeline file
Pipeline代碼如下:
pipeline{
agent any
environment {
PATH=$PATH:/opt/node/bin
}
stages{
stage("下載代碼"){
steps{
checkout([$class: 'GitSCM', branches: [[name: '*/master']], doGenerateSubmoduleConfigurations: false, extensions: [], submoduleCfg: [], userRemoteConfigs: [[credentialsId: 'b8c1f793-47ed-4903-995d-2273673d8f87', url: 'git@10.0.0.200:dev/h5game.git']]])
}
}
stage("檢測代碼"){
steps{
sh "/opt/sonar-scanner/bin/sonar-scanner \
-Dsonar.projectName=${JOB_NAME} \
-Dsonar.projectKey=html \
-Dsonar.sources=. \
-Dsonar.host.url=http://10.0.0.203:9000 \
-Dsonar.login=4f57dfb332463fa8220be49856a0f1d27c88a142"
}
}
stage("編譯代碼"){
steps{
echo "packge code OK"
}
}
stage("部署代碼"){
steps{
sh "sh -x /scripts/jenkins/deploy.sh"
}
}
}
}
部署腳本如下:
#!/bin/bash
PATH_CODE=/var/lib/jenkins/workspace/${JOB_NAME}
PATH_WEB=/usr/share/nginx
TIME=$(date +%Y%m%d-%H%M)
IP=10.0.0.7
#打包代碼
cd ${PATH_CODE}
tar zcf /opt/${TIME}-web.tar.gz ./*
#拷貝打包好的代碼發送到web服務器代碼目錄
ssh ${IP} "mkdir ${PATH_WEB}/${TIME}-web -p"
scp /opt/${TIME}-web.tar.gz ${IP}:${PATH_WEB}/${TIME}-web
#web服務器解壓代碼
ssh ${IP} "cd ${PATH_WEB}/${TIME}-web && tar xf ${TIME}-web.tar.gz && rm -rf ${TIME}-web.tar.gz"
ssh ${IP} "cd ${PATH_WEB} && rm -rf html && ln -s ${TIME}-web html"
jenkins配置如下:

4.構建

5.增加確認環節
生成交互確認的pipeline代碼

增加相關代碼片段:
pipeline{
agent any
stages{
stage("下載代碼"){
steps{
checkout([$class: 'GitSCM', branches: [[name: '*/master']], doGenerateSubmoduleConfigurations: false, extensions: [], submoduleCfg: [], userRemoteConfigs: [[credentialsId: 'b8c1f793-47ed-4903-995d-2273673d8f87', url: 'git@10.0.0.200:dev/h5game.git']]])
}
}
stage("檢測代碼"){
steps{
sh "/opt/sonar-scanner/bin/sonar-scanner \
-Dsonar.projectName=${JOB_NAME} \
-Dsonar.projectKey=html \
-Dsonar.sources=. \
-Dsonar.host.url=http://10.0.0.203:9000 \
-Dsonar.login=4f57dfb332463fa8220be49856a0f1d27c88a142"
}
}
stage("編譯代碼"){
steps{
echo "packge code OK"
}
}
stage("是否部署"){
steps{
input message: '確定要部署嗎?', ok: 'ok'
}
}
stage("部署代碼"){
steps{
sh "sh -x /scripts/jenkins/deploy.sh"
}
}
}
}
6.構建測試

此時會提示我們是否ok,點擊ok之后部署成功

7.增加構建結果通知動作
查詢通知語法

修改pipeleine增加相關代碼
pipeline{
agent any
stages{
stage("下載代碼"){
steps{
checkout([$class: 'GitSCM', branches: [[name: '*/master']], doGenerateSubmoduleConfigurations: false, extensions: [], submoduleCfg: [], userRemoteConfigs: [[credentialsId: 'b8c1f793-47ed-4903-995d-2273673d8f87', url: 'git@10.0.0.200:dev/h5game.git']]])
}
}
stage("檢測代碼"){
steps{
sh "/opt/sonar-scanner/bin/sonar-scanner \
-Dsonar.projectName=${JOB_NAME} \
-Dsonar.projectKey=html \
-Dsonar.sources=. \
-Dsonar.host.url=http://10.0.0.203:9000 \
-Dsonar.login=4f57dfb332463fa8220be49856a0f1d27c88a142"
}
}
stage("編譯代碼"){
steps{
echo "packge code OK"
}
}
stage("是否部署"){
steps{
input message: '確定要部署嗎?', ok: 'ok'
}
}
stage("部署代碼"){
steps{
sh "sh -x /scripts/jenkins/deploy.sh"
}
}
}
post {
success {
dingTalk accessToken: '878146e038041b550825b079049cafdf2db77b88221a81a75c9c684b42c80cc8', imageUrl: '', jenkinsUrl: '', message: 'pipeline構建成功', notifyPeople: ''
}
failure {
dingTalk accessToken: '878146e038041b550825b079049cafdf2db77b88221a81a75c9c684b42c80cc8', imageUrl: '', jenkinsUrl: '', message: 'pipeline構建失敗', notifyPeople: ''
}
}
}
8.構建測試

9.釘釘查看通知

第5章 pipeline改造java項目
1.git parameter官方地址
https://plugins.jenkins.io/git-parameter/
2.發布腳本
#!/bin/bash
PATH_CODE=/var/lib/jenkins/workspace/${JOB_NAME}
PATH_WEB=/opt/tomcat/webapps
IP=10.0.0.7
#拷貝war包發送到web服務器代碼目錄
code_scp(){
ssh ${IP} "mkdir ${PATH_WEB}/java-${git_version} -p"
scp ${PATH_CODE}/target/*.war ${IP}:${PATH_WEB}/java-${git_version}
}
#web服務器解壓代碼
code_unzip(){
ssh ${IP} "cd ${PATH_WEB}/java-${git_version} && unzip *.war && rm -rf *.war"
}
#創建代碼軟鏈接
code_ln(){
ssh ${IP} "cd ${PATH_WEB} && rm -rf ROOT && ln -s java-${git_version} ROOT"
}
#重啟tomcat
restart_tomcat(){
ssh ${IP} "cd /opt/tomcat/bin && ./shutdown.sh && ./startup.sh"
}
main(){
code_scp
code_unzip
code_ln
}
#選擇發布還是回滾
if [ "${deploy_env}" == "deploy" ]
then
ssh ${IP} "ls ${PATH_WEB}/java-${git_version}" >/dev/null 2>&1
if [ $? == 0 -a ${GIT_COMMIT} == ${GIT_PREVIOUS_SUCCESSFUL_COMMIT} ]
then
echo "java-${git_version} 已部署,不允許重復構建"
exit
else
main
restart_tomcat
fi
elif [ "${deploy_env}" == "rollback" ]
then
code_ln
restart_tomcat
fi
3.pipeline腳本
pipeline{
agent any
parameters {
gitParameter name: 'git_version',
branchFilter: 'origin/(.*)',
type: 'PT_TAG',
defaultValue: 'v1.0',
description: '發布新版本'
choice(name: 'deploy_env', choices: ['deploy','rollback'],description: 'deploy: 發布版本\nrollback: 回滾版本')
}
stages{
stage("下載代碼"){
steps{
checkout([$class: 'GitSCM',
branches: [[name: '${git_version}']],
doGenerateSubmoduleConfigurations: false,
userRemoteConfigs: [[credentialsId: 'b8c1f793-47ed-4903-995d-2273673d8f87',
url: 'git@10.0.0.200:dev/java-helloworld.git']]])
}
}
stage("檢測代碼"){
steps{
sh "/opt/sonar-scanner/bin/sonar-scanner \
-Dsonar.projectName=${JOB_NAME} \
-Dsonar.projectKey=${JOB_NAME} \
-Dsonar.sources=. \
-Dsonar.host.url=http://10.0.0.203:9000 \
-Dsonar.login=4f57dfb332463fa8220be49856a0f1d27c88a142"
}
}
stage("編譯代碼"){
steps{
sh "/opt/maven/bin/mvn package"
}
}
stage("是否部署"){
steps{
input message: '確定要部署嗎?', ok: 'ok'
}
}
stage("部署代碼"){
steps{
sh "sh -x /scripts/jenkins/java_deploy.sh"
}
}
}
post {
success {
dingTalk accessToken: '878146e038041b550825b079049cafdf2db77b88221a81a75c9c684b42c80cc8', imageUrl: '', jenkinsUrl: '', message: 'pipeline構建成功', notifyPeople: ''
}
failure {
dingTalk accessToken: '878146e038041b550825b079049cafdf2db77b88221a81a75c9c684b42c80cc8', imageUrl: '', jenkinsUrl: '', message: 'pipeline構建失敗', notifyPeople: ''
}
}
}
4.構建效果


第6章 jenkins分布式構建
1.分布式構建介紹
2.node節點安裝軟件
git
jdk
mvn
sonar-scanner
部署腳本
3.配置jenkins




4.node節點查看
[root@jenkins-204 ~]# ll /home/jenkins/
總用量 852
drwxr-xr-x 4 root root 34 8月 22 23:21 remoting
-rw-r--r-- 1 root root 872440 8月 22 23:21 remoting.jar
[root@jenkins-204 ~]# ps -ef|grep java
root 1521 1475 0 23:21 ? 00:00:00 bash -c cd "/home/jenkins" && java -jar remoting.jar -workDir /home/jenkins
root 1528 1521 1 23:21 ? 00:00:05 java -jar remoting.jar -workDir /home/jenkins
root 1655 1175 0 23:28 pts/0 00:00:00 grep --color=auto java
5.構建測試-指定在node節點構建
以h5項目舉例,修改pipeline代碼,指定在node節點構建
pipeline{
agent { label 'node1' }
stages{
stage("下載代碼"){
steps{
checkout([$class: 'GitSCM', branches: [[name: '*/master']], doGenerateSubmoduleConfigurations: false, extensions: [], submoduleCfg: [], userRemoteConfigs: [[credentialsId: 'b8c1f793-47ed-4903-995d-2273673d8f87', url: 'git@10.0.0.200:dev/h5game.git']]])
}
}
stage("檢測代碼"){
steps{
sh "/opt/sonar-scanner/bin/sonar-scanner \
-Dsonar.projectName=${JOB_NAME} \
-Dsonar.projectKey=html \
-Dsonar.sources=. \
-Dsonar.host.url=http://10.0.0.203:9000 \
-Dsonar.login=4f57dfb332463fa8220be49856a0f1d27c88a142"
}
}
stage("編譯代碼"){
steps{
echo "packge code OK"
}
}
stage("是否部署"){
steps{
input message: '確定要部署嗎?', ok: 'ok'
}
}
stage("部署代碼"){
steps{
sh "sh -x /scripts/jenkins/deploy.sh"
}
}
}
post {
success {
dingTalk accessToken: '878146e038041b550825b079049cafdf2db77b88221a81a75c9c684b42c80cc8', imageUrl: '', jenkinsUrl: '', message: 'pipeline構建成功', notifyPeople: ''
}
failure {
dingTalk accessToken: '878146e038041b550825b079049cafdf2db77b88221a81a75c9c684b42c80cc8', imageUrl: '', jenkinsUrl: '', message: 'pipeline構建失敗', notifyPeople: ''
}
}
}
執行效果如下:
ssssss
