前言
之前我們已經(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去完成的瘾敢。
思路
- 創(chuàng)建流水線任務(wù)
- jenkins管理節(jié)點(diǎn)中創(chuàng)建pod模板拍冠,并配置maven容器與docker容器
- pod配置-掛載卷 (主要為/root/.m2 以及 kubectl 和.kube下的配置)
- 配置 憑據(jù)(登錄habor的憑據(jù),git拉取代碼的憑據(jù))
- 流水線代碼
- 測試調(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ù))
2. 容器配置
maven打包構(gòu)建需要maven容器簇抵,docker打包上傳鏡像需要docker容器
三. 掛載卷
有些目錄或者數(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厢洞,有興趣的可以自己了解一下。
- 查看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
- jenkins-pod模板--容器配置處公你,添加卷(注意類型)
四. 配置憑據(jù)
系統(tǒng)管理---安全---Manage Credentials
需要配2個(gè)憑據(jù):
- 拉代碼用到訪問gitlab項(xiàng)目的憑據(jù)
- docker推鏡像用到的Docker login憑據(jù)
以下為docker憑據(jù)配置踊淳,gitlab配置的方式同理
五. 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ā)布
——————————————————————————————————————————————————
關(guān)于jenkins變量引用用單引還是雙引的問題
jenkins 中和shell語法是一致的。
- 要引用的是普通字符陕靠,單雙引號都可以迂尝。
- 引用的內(nèi)容中有需要解釋的符號,如提取變量的$需要用
雙引號
- 但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)過測試,雙引號就解析不出來變量税肪。
- 如果需要用雙引號里面的命令還需要用雙引號溉躲,那可以利用轉(zhuǎn)義,如
sh "sed -i \"s#IMAGE_NAME#${IMAGE_NAME}#g\" deploy/test/k8sdeployment.yaml"
To Do List :
job的workspace掛載出來益兄,省去每次都重新去拉代碼(已更新)
通過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è)置中
設(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
不用每次都重新拉代碼了: