Jenkins agent-Java項(xiàng)目實(shí)踐

前言

之前我們已經(jīng)將jenkins agent環(huán)境搭建好(基于docker或k8s動態(tài)創(chuàng)建)悲没,并且已經(jīng)通過流水線跑通了一個(gè)Demo示例,基于前面搭建的環(huán)境旗扑,實(shí)際項(xiàng)目中針對后端java項(xiàng)目如何通過agent進(jìn)行發(fā)布呢小泉? 其實(shí)主要思路還是跟以前一樣的:

  • 拉代碼
  • maven構(gòu)建打包
  • 構(gòu)建鏡像
  • 上傳至私有鏡像倉庫
  • 部署服務(wù)
    只不過現(xiàn)在這些事情由jenkins master全權(quán)交給agent來做, agent做完即銷毀晶默。

注意:k8s的方式中,jenkins agent是一個(gè)pod航攒,而一個(gè)pod可以是一組容器磺陡,在這一個(gè)pod中這一組容器的數(shù)據(jù)是共享的,所以系統(tǒng)默認(rèn)會有一個(gè)jnlp的容器用來agent與master連接這是一個(gè)必須有的容器漠畜,我們還可以在這個(gè)pod中加一個(gè)maven的容器來實(shí)現(xiàn)maven構(gòu)建打包的階段币他。當(dāng)然了,也可以將這個(gè)jnlp容器重構(gòu)憔狞,加入docker,maven等相關(guān)工具只用這個(gè)鏡像去完成也可以蝴悉,不過目前我還沒這么做,只是聚集需要的容器在一個(gè)pod中作為一個(gè)整體agent去完成的瘾敢。

思路

  1. 創(chuàng)建流水線任務(wù)
  2. jenkins管理節(jié)點(diǎn)中創(chuàng)建pod模板拍冠,并配置maven容器與docker容器
  3. pod配置-掛載卷 (主要為/root/.m2 以及 kubectl 和.kube下的配置)
  4. 配置 憑據(jù)(登錄habor的憑據(jù),git拉取代碼的憑據(jù))
  5. 流水線代碼
  6. 測試調(diào)試發(fā)布

一.創(chuàng)建流水線任務(wù)

新建任務(wù)--流水線--填寫名稱(略)

二.創(chuàng)建Pod模板

1. 模板配置

系統(tǒng)管理-->節(jié)點(diǎn)管理-->Configure Clouds-->Pod Temlates-->填寫pod模板名稱-->detalis展開更詳細(xì)配置
-->填寫命名空間-->agent標(biāo)簽列表(后期通過這個(gè)標(biāo)簽名去調(diào)用相應(yīng)的一組agent pod來完成任務(wù))

1-java實(shí)踐-模板置1.png

2. 容器配置

maven打包構(gòu)建需要maven容器簇抵,docker打包上傳鏡像需要docker容器

1-jenkins實(shí)踐-容器配置1.png
1-jenkins實(shí)踐-容器配置2.png

三. 掛載卷

有些目錄或者數(shù)據(jù)需要掛載到pod中庆杜,這里我是有一臺nfs服務(wù)器(搭建過程略),如果沒有nfs存儲服務(wù)器那么就需要k8s集群中每臺機(jī)器都需要放一份相同數(shù)據(jù)了哦~

需要掛載:maven構(gòu)建需要的/root/.m2碟摆; kubectl以及鏈接的config文件晃财; 宿主機(jī)上的docker.sock;rancher工具(看需求)典蜕;

注意:我們配置了docker容器断盛,經(jīng)過測試如果不將docker.sock進(jìn)程掛載進(jìn)去的話,是無法在docker中操作docker的愉舔。
這樣掛出來也是比較省事的方法钢猛,也是用的比較多的方案,這種操作跟宿主機(jī)的docker是同步的屑宠。還有一種叫dind厢洞,有興趣的可以自己了解一下。

  1. 查看nfs共享的目錄里都有哪些東西?
# nfs共享目錄
# showmount -e 
Export list for k8s01.test.hw:
/opt/jenkins_agent_data          *

/opt/jenkins_agent_data# ls -a
.  ..  _data  .kube  rancher-tools  .ssh.bak

/opt/jenkins_agent_data/_data下放的是/root/.m2的數(shù)據(jù)躺翻,將其掛載出來避免每次啟動maven agent都會拉一遍所有依賴

/opt/jenkins_agent_data/_data
root@k8s01.test.hw:/opt/jenkins_agent_data/_data# ls
copy_reference_file.log  repository  settings-docker.xml  settings.xml  settings.xml-bak-20211117  settings.xml-bak-20211118  settings.xml.bak_20220711

.kube包含了kubectl工具和k8s集群的config文件,用于在agent直接可發(fā)布項(xiàng)目至k8s集群

root@k8s01.test.hw:/opt/jenkins_agent_data/.kube#  ls
cache  config  config.dev  config.uat  kubectl

rancher-tools中為rancher工具丧叽,跟kubectl一樣,是用來發(fā)布項(xiàng)目至rancher集群中(如果你沒有rancher集群項(xiàng)目請忽略)

root@k8s01.test.hw:/opt/jenkins_agent_data/rancher-tools# ls
rancher
  1. jenkins-pod模板--容器配置處公你,添加卷(注意類型)
2-jenkins實(shí)踐-卷配置1.png
2-jenkins實(shí)踐-卷配置2.png

四. 配置憑據(jù)

系統(tǒng)管理---安全---Manage Credentials

需要配2個(gè)憑據(jù):

  1. 拉代碼用到訪問gitlab項(xiàng)目的憑據(jù)
  2. docker推鏡像用到的Docker login憑據(jù)
    以下為docker憑據(jù)配置踊淳,gitlab配置的方式同理
3-jenkins實(shí)踐-憑據(jù)管理1.png
3-jenkins實(shí)踐-憑據(jù)管理2.png

五. Pipeline編寫

發(fā)布至k8s

agent.label這里要寫之前配置的pod標(biāo)簽

pipeline {
    agent {
         label 'mavenpod' 
    }
    options {
        skipDefaultCheckout()
    }
    environment {
        IMAGE_REPO = "harbor.hw.xxxx:5000/k8s-test"
        PROJECT_NAME = "health-cloud-evaluation"
        RUN_ENV = "k8s-dev"
    }
    stages {
        stage('get code'){
            steps{
                    git branch: 'tianye-cicd', credentialsId: '248e1fa0-6165-4a81-8297-4107e413207c', url: 'https://gitlab.xxxx.com/java-dev/health-cloud-biz/health-cloud-evaluation.git'
                    //git branch: 'dev', credentialsId: '248e1fa0-6165-4a81-8297-4107e4132017c', url: 'git@gitlab.xxxx.com:java-dev/health-cloud-biz/health-cloud-evaluation.git'
                    // get image-version
                    script {
                            env.GIT_COMMIT_MSG = sh (script: 'git rev-parse --short=8 HEAD', returnStdout: true).trim()
                            IMAGE_VERSION = "${GIT_COMMIT_MSG}-${RUN_ENV}"
                            IMAGE_NAME = "${IMAGE_REPO}/${PROJECT_NAME}:${IMAGE_VERSION}"
                    }    
            }
        }
        stage('maven build'){
            steps{
                container('maven-agent') {
                       sh 'mvn clean package -DskipTests -Pdev'
                }
            }
        }
        stage('build image'){
            steps{
                container('docker-agent') {
                    withCredentials([usernamePassword(credentialsId: 'ee78c0ce-d905-4c2c-bbf0-928f1a9f17d0', passwordVariable: 'docker_password', usernameVariable: 'docker_username')]) {
                        sh 'docker login -u ${docker_username} -p ${docker_password} ${IMAGE_REPO}'
                        sh "docker build -t ${PROJECT_NAME}:${IMAGE_VERSION} -f deploy/test/Dockerfile ."
                        sh "docker tag ${PROJECT_NAME}:${IMAGE_VERSION}  ${IMAGE_REPO}/${PROJECT_NAME}:${IMAGE_VERSION}"
                        sh "docker push ${IMAGE_REPO}/${PROJECT_NAME}:${IMAGE_VERSION}"
                        sh 'echo build images success'
                    }
                       
                }
            }
        }
        stage('deploy to k8s'){
            steps{
                sh "sed -i \"s#IMAGE_NAME#${IMAGE_NAME}#g\" deploy/test/k8sdeployment.yaml"
                sh "/home/jenkins/.kube/kubectl apply -f deploy/test/k8sdeployment.yaml"
            }
        }
        stage('health-check'){
            steps{
                sh '/home/jenkins/.kube/kubectl rollout status -n nacos deployment ${PROJECT_NAME}'
            }
        }
        
    }
}
發(fā)布至Rancher
pipeline {
   agent {
        label 'mavenpod' 
   }
   options {
       skipDefaultCheckout()
   }
   environment {
       IMAGE_REPO = "harbor.hw.xxx.com:5000/k8s-test"
       PROJECT_NAME = "health-cloud-evaluation"
       RUN_ENV = "dev"
       OLD_IMAGE = "harbor.hw.xxxx.com:5000/health-cloud-server/health-cloud-evaluation:latest"
   }
   stages {
       stage('get code'){
           steps{
                   git branch: 'tianye-cicd', credentialsId: '248e1fa0-6165-4a81-8297-4107e4131207c', url: 'https://gitlab.xxxx.com/java-dev/health-cloud-biz/health-cloud-evaluation.git'
                   //git branch: 'dev', credentialsId: '248e1fa0-6165-4a81-8297-4107e4132017c', url: 'git@gitlab.xxx.com:java-dev/health-cloud-biz/health-cloud-evaluation.git'
                   // get image version
                   script {
                           env.GIT_COMMIT_MSG = sh (script: 'git rev-parse --short=8 HEAD', returnStdout: true).trim()
                           IMAGE_VERSION = "${GIT_COMMIT_MSG}-${RUN_ENV}"
                           IMAGE_NAME = "${IMAGE_REPO}/${PROJECT_NAME}:${IMAGE_VERSION}"
                   } 
           }
       }
       stage('maven build'){
           steps{
               container('maven-agent') {
                      sh "sed -i \"s#${OLD_IMAGE}#${IMAGE_NAME}#g\" deploy/test/docker-compose.yml"
                      sh 'mvn clean package -DskipTests -Pdev'
               }
           }
       }
       stage('build image'){
           steps{
               container('docker-agent') {
                   withCredentials([usernamePassword(credentialsId: 'ee78c0ce-d905-4c2c-bbf0-928f1a9f17d0', passwordVariable: 'docker_password', usernameVariable: 'docker_username')]) {
                       sh 'docker login -u ${docker_username} -p ${docker_password} ${IMAGE_REPO}'
                       sh "docker build -t ${PROJECT_NAME}:${IMAGE_VERSION} -f deploy/test/Dockerfile ."
                       sh "docker tag ${PROJECT_NAME}:${IMAGE_VERSION}  ${IMAGE_REPO}/${PROJECT_NAME}:${IMAGE_VERSION}"
                       sh "docker push ${IMAGE_REPO}/${PROJECT_NAME}:${IMAGE_VERSION}"
                       sh 'echo build images success'
                   }
                      
               }
           }
       }
       stage('deploy to rancher'){
           steps{
               sh '/home/jenkins/rancher-tools/rancher --url https://dev.hw.xxxxrancher.com/ --access-key 926407BB131AE8EE5010 --secret-key ksPBDn1fr97bjzAqYk5KaVU8aRfLQF6UHxFdtfwP2 --env 1a5 up -s health-cloud-server -d  -f deploy/test/docker-compose.yml --rancher-file deploy/test/rancher-compose.yml --pull --upgrade --confirm-upgrade'
           }
       }
   }
}

六. 測試發(fā)布

3-jenkins實(shí)踐-結(jié)果1.png

——————————————————————————————————————————————————

關(guān)于jenkins變量引用用單引還是雙引的問題

jenkins 中和shell語法是一致的。

  1. 要引用的是普通字符陕靠,單雙引號都可以迂尝。
  2. 引用的內(nèi)容中有需要解釋的符號,如提取變量的$需要用雙引號
  3. 但jenkins的流水線聲明的env變量中剪芥,解析它的變量用單引號
    如:
   withCredentials([usernamePassword(credentialsId: 'ee78c0ce-d905-4c2c-bbf0-928f1a9f171d0', passwordVariable: 'docker_password', usernameVariable: 'docker_username')]) {
                       sh 'docker login -u ${docker_username} -p ${docker_password} ${IMAGE_REPO}'

這一段中垄开,經(jīng)過測試,雙引號就解析不出來變量税肪。

  1. 如果需要用雙引號里面的命令還需要用雙引號溉躲,那可以利用轉(zhuǎn)義,如
       sh "sed -i \"s#IMAGE_NAME#${IMAGE_NAME}#g\" deploy/test/k8sdeployment.yaml"

To Do List :

  1. job的workspace掛載出來益兄,省去每次都重新去拉代碼(已更新)

  2. 通過git-commit號來作為鏡像版本標(biāo)識锻梳,更加有助于回滾 (已更新)


20230220更新:

agent構(gòu)建的時(shí)候,持久化數(shù)據(jù)也是有必要的净捅,不然首先麻煩的就每次都要重新拉取代碼疑枯,嘗試把a(bǔ)gent工作目錄掛載到宿主機(jī):

1.將agent的工作目錄掛載到nfs服務(wù)器上:
系統(tǒng)管理---節(jié)點(diǎn)管理---找到你的cloud--pod模板設(shè)置中


7-工作目錄掛載.png

設(shè)置后,會自動將agent的工作路徑/home/jenkins/agent下的workspace掛載到nfs服務(wù)器的/opt/jenkins_agent_workspace下

查看一下(workspace下job名蛔六,而下面就是各job下的數(shù)據(jù)):

root@k8s01.test.hw:/opt/jenkins_agent_workspace# ls workspace/
k8s-test_health-cloud-evaluation  k8s-test_health-cloud-evaluation@tmp  test-bottom-library_H5-node12.20.2  test-bottom-library_H5-node12.20.2@tmp
root@k8s01.test.hw:/opt/jenkins_agent_workspace# pwd
/opt/jenkins_agent_workspace

不用每次都重新拉代碼了:


7-掛在后效果.png
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末荆永,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子古今,更是在濱河造成了極大的恐慌屁魏,老刑警劉巖滔以,帶你破解...
    沈念sama閱讀 216,324評論 6 498
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件捉腥,死亡現(xiàn)場離奇詭異,居然都是意外死亡你画,警方通過查閱死者的電腦和手機(jī)抵碟,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,356評論 3 392
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來坏匪,“玉大人拟逮,你說我怎么就攤上這事∈首遥” “怎么了敦迄?”我有些...
    開封第一講書人閱讀 162,328評論 0 353
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經(jīng)常有香客問我罚屋,道長苦囱,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,147評論 1 292
  • 正文 為了忘掉前任脾猛,我火速辦了婚禮撕彤,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘猛拴。我一直安慰自己羹铅,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,160評論 6 388
  • 文/花漫 我一把揭開白布愉昆。 她就那樣靜靜地躺著职员,像睡著了一般。 火紅的嫁衣襯著肌膚如雪跛溉。 梳的紋絲不亂的頭發(fā)上廉邑,一...
    開封第一講書人閱讀 51,115評論 1 296
  • 那天,我揣著相機(jī)與錄音倒谷,去河邊找鬼蛛蒙。 笑死,一個(gè)胖子當(dāng)著我的面吹牛渤愁,可吹牛的內(nèi)容都是我干的牵祟。 我是一名探鬼主播,決...
    沈念sama閱讀 40,025評論 3 417
  • 文/蒼蘭香墨 我猛地睜開眼抖格,長吁一口氣:“原來是場噩夢啊……” “哼诺苹!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起雹拄,我...
    開封第一講書人閱讀 38,867評論 0 274
  • 序言:老撾萬榮一對情侶失蹤收奔,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后滓玖,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體坪哄,經(jīng)...
    沈念sama閱讀 45,307評論 1 310
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,528評論 2 332
  • 正文 我和宋清朗相戀三年势篡,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了翩肌。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 39,688評論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡禁悠,死狀恐怖念祭,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情碍侦,我是刑警寧澤粱坤,帶...
    沈念sama閱讀 35,409評論 5 343
  • 正文 年R本政府宣布隶糕,位于F島的核電站,受9級特大地震影響站玄,放射性物質(zhì)發(fā)生泄漏若厚。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,001評論 3 325
  • 文/蒙蒙 一蜒什、第九天 我趴在偏房一處隱蔽的房頂上張望测秸。 院中可真熱鬧,春花似錦灾常、人聲如沸霎冯。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,657評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽沈撞。三九已至,卻和暖如春雕什,著一層夾襖步出監(jiān)牢的瞬間缠俺,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,811評論 1 268
  • 我被黑心中介騙來泰國打工贷岸, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留壹士,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 47,685評論 2 368
  • 正文 我出身青樓偿警,卻偏偏與公主長得像躏救,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個(gè)殘疾皇子螟蒸,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,573評論 2 353

推薦閱讀更多精彩內(nèi)容