使⽤Jenkinspipeline流⽔线构建docker镜像和发布
新建⼀个pipeline job
选择Pipeline任务,然后进⼊配置页⾯。
对于Pipeline, Definition选择 "Pipeline script from SCM".
需要注意的是Script Path, 这⾥要指定项⽬中Jenkinsfile⽂件的具体位置。默认是根⽬录。我这⾥是maven的⼀个⼦模块,所以嵌套⼀层。
项⽬中添加Jenkinsfile
以下是我⾃⼰的Jenkinsfile,这⾥⽤作注释和备忘
node('slave001') {
stage('Prepare') {
echo "1.Prepare Stage"
checkout scm
pom = readMavenPom file: 'l'
docker_host = "an-miao"
img_name = "${upId}-${pom.artifactId}"
docker_img_name = "${docker_host}/${img_name}"
echo "group: ${upId}, artifactId: ${pom.artifactId}, version: ${pom.version}"
echo "docker-img-name: ${docker_img_name}"
script {
build_tag = sh(returnStdout: true, script: 'git rev-parse --short HEAD').trim()
if (env.BRANCH_NAME != 'master' && env.BRANCH_NAME != null) {
docker打包镜像build_tag = "${env.BRANCH_NAME}-${build_tag}"
}
}
}
stage('Test') {
echo "2.Test Stage"
sh "mvn test"
}
stage('Build') {
echo "3.Build Docker Image Stage"
sh "mvn package -st.skip=true"
sh "docker build -t ${docker_img_name}:${build_tag} " +
" --build-arg SPRING_PROFILE=prod " +
" --build-arg JAR_FILE=target/${pom.artifactId}-${pom.version}.jar " +
" ./location/"
}
stage('Push') {
echo "4.Deploy jar and Push Docker Image Stage"
sh "mvn deploy -st.skip=true"
sh "docker tag ${docker_img_name}:${build_tag} ${docker_img_name}:latest"
sh "docker tag ${docker_img_name}:${build_tag} ${docker_img_name}:${pom.version}"
withCredentials([usernamePassword(credentialsId: 'docker-register', passwordVariable: 'dockerPassword', usernameVariable: 'dockerUser')]) { sh "docker login -u ${dockerUser} -p ${dockerPassword} an-miao"
sh "docker push ${docker_img_name}:latest"
sh "docker push ${docker_img_name}:${pom.version}"
sh "docker push ${docker_img_name}:${build_tag}"
}
}
//stash 'complete-build'
}
if (env.BRANCH_NAME == 'master' || env.BRANCH_NAME == null) {
timeout(time: 10, unit: 'MINUTES') {
input '确认要部署线上环境吗?'
}
}
node('slave001'){
stage('Deploy') {
//unstash 'complete-build'
echo "5. Deploy Stage"
sh "sed -i 's/<IMG_NAME>/${img_name}:${build_tag}/' location/k8s.yaml"
sh "sed -i 's/<BRANCH_NAME>/${env.BRANCH_NAME}/' location/k8s.yaml"
sh "/data/opt/kubernetes/client/bin/kubectl apply -f ${WORKSPACE}/location/k8s.yaml --record"
}
}
node('slave001') { 最外层必须是node节点,这⾥单独制定运⾏的jenkins节点,通常不⽤指定,由jenkins master分配任务即可。这种写法属于Scripted Pipeline。
stage('Prepare') {} stage是⼀个阶段的语法,括号⾥阶段名称。脚本从node开始,按顺序向下执⾏。遇到的第⼀个stage就是第⼀个阶段。
使⽤echo xxxx来输出⽂字,给出进度信息。
checkout scm 是Jenkins固定获取代码的⽅法,会输出Check out from version control。
pom = readMavenPom file: 'l' 是读取workspace下相对⽬录的pom⽂件。这个需要Jenkins 安装插件。通过${upId}-${pom.artifactId}来获取pom信息. 我的pom在⼦module location⾥。
docker_host = "an-miao" 声明⼀个全局的变量,如果只想在⽅法体 {}中使⽤,可以加def。
${docker_host} 变量可以通过这样类似shell的⽅式获取。
build_tag = sh(returnStdout: true, script: 'git rev-parse --short HEAD').trim() ⽤来获取git的commit id
Build阶段执⾏docker命令打包,把我们的变量传递到Dockerfile. 我的Dockerfile同样在⼦module location下。
withCredentials可以调⽤存储在Jenkins⾥的凭证。这个需要安装.
input会产⽣⼀个交互式的按钮,需要⼿动点击通过才会继续,否则暂停。这个只是暂停下⼀步,线程还在运⾏。所以,需要单独提出node之外,再添加⼀个超时设置。参见stash暂存⽂件,参见. 主要⽤来把这次build过程中的某个⽂件给暂存,只在本次build有效。本次不需要。
timeout 主要⽤来设置超时,参见, 时间单位有: NANOSECONDS, MICROSECONDS, MILLISECONDS, SECONDS, MINUTES, HOURS, DAYS。这⾥等待⽤户确认是否继续,若超过10分钟还没有确认,则停⽌。
看起来,似乎完美的从代码编译,打包,构建docker镜像,推送到仓库,设置触发了部署。但离真正⽣产⽅案还有距离。因为你不可能编译结束就直接上⽣产。真实的流程应该是:checkout->build->test-> 部署到测试环境 -> 对测试环境的⾃动化测试 -> 部署到⽣产环境。
如何做到build once, deploy many
我这⾥的pipeline步骤⾥没有多环境串联部署。这⾥部署到测试环境了,如果测试通过之后,想要部署⽣产环境应该怎么下⼀步呢?想要⼿动点⼀下某个按钮,就可以将部署在测试环境的这个版本的镜像部署到prod。input显然不满⾜需求。
第⼀,记录当前测试环境的镜像id;第⼆,提供⼀个⽣产prod job,可以⼿动输⼊镜像id进⾏部署.
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论