DevOps實戰(Docker+Jenkins+Git)


基於Docker+Jenkins+Git的CI/CD實戰

與上一篇隨筆:基於 Jenkins+Docker+Git 的CI流程初探 有所不同,該內容更偏向於實際業務的基礎需求。

有幾點需要注意:

  • 該實戰中沒有涉及到鏡像倉庫,所以略去了鏡像推送階段,可以參考基於 Jenkins+Docker+Git 的CI流程初探
  • 與上一篇對比,該實戰是基於外網服務器進行的,所以加入了Jenkins自動觸發拉取代碼以及發送構建報告功能。
  • 實戰中的Jenkins也是基於docker運行,對於Jenkins數據持久化是通過VOLUME實現的。
  • 不再進行自建git代碼倉庫,選擇使用Gitee管理代碼。
  • 實驗環境均已提前准備完畢。

1、Jenkins啟動

docker run \
 -u root \
 -d \
 -p 8080:8080 \
 -p 50000:50000 \
 -v jenkins-data:/var/jenkins_home \
 -v /etc/localtime:/etc/localtime:ro \
 -v /var/run/docker.sock:/var/run/docker.sock \
 --restart=always \
 jenkinsci/blueocean

啟動后設置用戶與密碼

2、新建item

名稱:java-devops-demo

創建流水線

選擇保存

Jenkins流水線工作流程:

  先定義一個流水線項目,指定項目的git位置

  流水線啟動

  a.先去git位置自動拉取代碼

  b.解析拉取代碼里面的Jenkinsfile文件

  c.按照Jenkinsfile指定的流水線開始加工項目

Jenkins重要的點

  1) jenkins的家目錄 /var/jenkins_home 已經被我們docker外部掛載了/var/lib/docker/volumes/jenkins-data/_data

  2)WORKSPACE(工作空間)=/var/jenkins_home/workspace/java-devops-demo每一個流水線項目,占用一個文件夾位置

  3)BUILD_NUMBER=5;當前第幾次構建

  4)WORKSPACE_TMP(臨時目錄)=/var/jenkins_home/workspace/java-devops-demo@tmp 

3、定義Jenkinsfile與Dockerfile具體內容

Jenkinsfile部分是逐步測試,按階段寫成。

pipeline{
    //全部的CI/CD流程都需要在這里定義
    //任何一個代理可用就可以執行
    agent any

    //定義一些環境信息
    environment {
      WS = "${WORKSPACE}"
    }

    //定義流水線的加工流程
    stages{

        stage('環境檢查'){
            steps {
               sh 'printenv'
               echo "正在檢測基本信息"
               sh 'java -version'
               sh 'git --version'
               sh 'docker version'
               sh 'pwd && ls -alh'
            }
        }

        //1、編譯 "abc"
        stage('maven編譯'){
            agent {
                docker {
                    image 'maven:3-alpine'
                    args '-v /var/jenkins_home/appconfig/maven/.m2:/root/.m2'
                    //docker run -v /var/jenkins_home/appconfig/maven/.m2:/root/.m2
                }
            }
            //要做的所有事情
            //jenkins不配置任何環境的情況下, 僅適用docker兼容所有場景
            steps{
                echo "編譯..."
                sh 'pwd && ls -alh'
                sh 'cd ${WS} && mvn clean package -s "/var/jenkins_home/appconfig/maven/settings.xml" -Dmaven.test.skip=true'
            }
        }
//2、打包
        stage('生成鏡像'){
            steps{
                sh 'pwd && ls -alh'
                sh 'docker version'
                sh 'docker build -t java-devops-demo .'
            }
        }

        //3、部署
        stage('部署'){
            steps{
                echo "部署..."
                sh 'docker rm -f java-devops-demo-dev'
                sh 'docker run -d -p 80:8080 --name java-devops-demo-dev java-devops-demo'
            }
        }

        //4、推送報告
        stage("發送報告"){
            steps {
                //短信通知,購買api接口即可
//                 sh 'curl -i -k -X POST 'https://gyytz.market.alicloudapi.com/sms/smsSend?mobile=mobile&param=**code**%3A12345%2C**minute**%3A5&smsSignId=2e65b1bb3d054466b82f0c9d125465e2&templateId=908e94ccf08b4476ba6c876d13f084ad'  -H 'Authorization:APPCODE dddddddd''
                //REST API 所有都行
//                 sh 'curl '
                echo '准備發送報告'
                emailext body: '''<!DOCTYPE html>
                <html>
                <head>
                <meta charset="UTF-8">
                <title>${ENV, var="JOB_NAME"}-第${BUILD_NUMBER}次構建日志</title>
                </head>

                <body leftmargin="8" marginwidth="0" topmargin="8" marginheight="4"
                    offset="0">
                    <table width="95%" cellpadding="0" cellspacing="0"  style="font-size: 11pt; font-family: Tahoma, Arial, Helvetica, sans-serif">
                <h3>本郵件由系統自動發出,請勿回復!</h3>
                        <tr>
                           <br/>
                            各位同事,大家好,以下為${PROJECT_NAME }項目構建信息</br>
                            <td><font color="#CC0000">構建結果 - ${BUILD_STATUS}</font></td>
                        </tr>
                        <tr>
                            <td><br />
                            <b><font color="#0B610B">構建信息</font></b>
                            <hr size="2" width="100%" align="center" /></td>
                        </tr>
                        <tr>
                            <td>
                                <ul>
                                    <li>項目名稱 : ${PROJECT_NAME}</li>
                                    <li>構建編號 : 第${BUILD_NUMBER}次構建</li>
                                    <li>觸發原因: ${CAUSE}</li>
                                    <li>構建狀態: ${BUILD_STATUS}</li>
                                    <li>構建日志: <a href="${BUILD_URL}console">${BUILD_URL}console</a></li>
                                    <li>構建  Url : <a href="${BUILD_URL}">${BUILD_URL}</a></li>
                                    <li>工作目錄 : <a href="${PROJECT_URL}ws">${PROJECT_URL}ws</a></li>
                                    <li>項目  Url : <a href="${PROJECT_URL}">${PROJECT_URL}</a></li>
                                </ul>


                <h4><font color="#0B610B">最近提交</font></h4>
                <ul>
                <hr size="2" width="100%" />
                ${CHANGES_SINCE_LAST_SUCCESS, reverse=true, format="%c", changesFormat="<li>%d [%a] %m</li>"}
                </ul>
                詳細提交: <a href="${PROJECT_URL}changes">${PROJECT_URL}changes</a><br/>

                            </td>
                        </tr>
                    </table>
                </body>
                </html>''', subject: '${ENV, var="JOB_NAME"}-第${BUILD_NUMBER}次構建日志', to: 'xxxxx@163.com'
            }
        }
    }
        //后置處理過程
        post {
          failure {
            echo "這個階段 完蛋了.... $currentBuild.result"
          }
          success {
            echo "這個階段 成了.... $currentBuild.result"
          }
        }
}

Dockerfile:

#這個也得有
FROM openjdk:8-jre-alpine
LABEL maintainer="xxxxxxx@qq.com"
#復制打好的jar包
COPY target/*.jar /app.jar
RUN  apk add -U tzdata; \
ln -sf /usr/share/zoneinfo/Asia/Shanghai /etc/localtime; \
echo 'Asia/Shanghai' >/etc/timezone; \
touch /app.jar;

ENV JAVA_OPTS=""
ENV PARAMS=""

EXPOSE 8080

ENTRYPOINT [ "sh", "-c", "java -Djava.security.egd=file:/dev/./urandom $JAVA_OPTS -jar /app.jar $PARAMS" ]

Jenkinsfile與Dockerfile均位於java-devops-jemo目錄下,由Jenkins從git倉庫拉取。

4、遠程構建觸發

期望效果: 遠程的github代碼提交了,jenkins流水線自動觸發構建。 

實現條件:

  • 保證jenkins所在主機能被遠程訪問。
  • jenkins中遠程觸發需要權限,我們應該使用用戶進行授權。
  • 配置gitee,webhook進行觸發。

實現過程:

1)進入流水線配置頁,填入身份驗證令牌

 2)遠程構建即使配置了gitee/github 的webhook,默認會403。我們應該使用用戶進行授權 

  a.創建一個用戶 (主界面>管理Jenkins>管理user>新建用戶)

  b.新建用戶后一定要重新登陸激活一次,進入用戶列表>點擊當前用戶名>設置

  c.生成一個apitoken (生成后立即復制,只出現一次)

3)碼雲端配置WebHooks,進入碼雲對應代碼倉庫-配置-WebHooks-添加WebHook

URL配置格式:http://dk:用戶dk的apitoken@主機的公網ip:8080/job/java-devops-demo/build?token=身份驗證令牌

添加成功后可測試與Jenkins主機的連通性。

至此,當本地修改代碼,git push提交到gitee/github后,Jenkins就能夠自動構建,構建成功即可查看前端頁面的變化。

5、配置maven環境

(使用自定義agent的方式引入maven環境,利用多階段構建不同場景下的復雜環境)

1)安裝docker pipeline插件

2)自定義agent(在stages內部)

3)配置maven加速(配置國內阿里雲)

把Maven的配置文件放在jenkins-data里面的某個位置。默認所有的可變配置項都推薦放在jenkins-home的位置,增強移植性。

4)緩存必要jar包,下次構建無需下載

agent {
    docker {
        image 'maven:3-alpine' //用完就會殺掉
        args '-v /var/jenkins_home/appconfig/maven/.m2:/root/.m2'
        // 將jar包映射到宿主機上/var/jenkins_home/appconfig/maven/.m2目錄中
        // 也可以將jar包以數據卷方式掛載到宿主機
    }
}
注:jenkins不配置任何環境的情況下, 僅適用docker兼容所有場景。
  • 臨時容器導致的問題(每個stage都會回到默認workspace,臨時容器產生的打包數據不能被利用)
    • 第一次檢出代碼,默認在 /var/jenkins_home/workspace/【java-devops-demo】
    • 使用docker臨時agent的時候,每一個臨時容器運行又分配臨時目錄 /var/jenkins_home/workspace/java-devops-demo@2;默認就是workspace/java-devops-demo 的內容
    • 在臨時容器里面 運行的mvn package命令,會在 /var/jenkins_home/workspace/java-devops-demo@2 進行工作 
    • package到了 /var/jenkins_home/workspace/java-devops-demo@2 位置
    • 進入下一步(stage)進行打包鏡像,又會回到 /var/jenkins_home/workspace/【java-devops-demo】(默認workspace)這個位置
    •  這個位置沒有運行過 mvn clean package ,所以沒有target。 默認的 工作目錄 沒有 target

     解決方法:在臨時容器內部切換到Jenkins的默認工作目錄,再進行maven打包。

6、郵件推送

使用郵件擴展插件:Email Extension Plugin-2.71 (對於每個stage執行的任務成功與否可以通過后置執行post來進行感知)

系統管理>系統配置>配置管理員郵箱(系統管理員郵件地址)、SMTP服務相關及其他

  

下圖Use SMTP Authentication部分在高版本插件中已不再支持

填寫完畢,可以通過發送測試郵件進行測試。

上圖的郵件用戶的授權碼需要配置郵件發送的認證權限信息

  1. 登錄自己郵箱,開啟POP3/SMTP郵件服務
  2. 獲取到自己的授權碼(tlqhksolsmeodjad)
  3. 配置並測試好郵件發送即可

郵件模板內容見Jenkinsfile中報告推送階段。

至此,開發提交代碼后,將自動觸發構建過程,構建結束后發送此次構建郵件報告如下:


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM