新建一个pipeline job

选择Pipeline任务,然后进入配置页面。

对于Pipeline, Definition选择 "Pipeline script from SCM".

需要注意的是Script Path, 这里要指定项目中Jenkinsfile文件的具体位置。默认是根目录。我这里是maven的一个子模块,所以嵌套一层。

项目中添加Jenkinsfile

关于Jenkinsfile可以查阅w3c翻译整理的文档: https://www.w3cschool.cn/jenkins/jenkins-qc8a28op.html

以下是我自己的Jenkinsfile,这里用作注释和备忘

  1. node('slave001') {
  2. stage('Prepare') {
  3. echo "1.Prepare Stage"
  4. checkout scm
  5. pom = readMavenPom file: 'location/pom.xml'
  6. docker_host = "docker.ryan-miao.com"
  7. img_name = "${pom.groupId}-${pom.artifactId}"
  8. docker_img_name = "${docker_host}/${img_name}"
  9. echo "group: ${pom.groupId}, artifactId: ${pom.artifactId}, version: ${pom.version}"
  10. echo "docker-img-name: ${docker_img_name}"
  11. script {
  12. build_tag = sh(returnStdout: true, script: 'git rev-parse --short HEAD').trim()
  13. if (env.BRANCH_NAME != 'master' && env.BRANCH_NAME != null) {
  14. build_tag = "${env.BRANCH_NAME}-${build_tag}"
  15. }
  16. }
  17. }
  18. stage('Test') {
  19. echo "2.Test Stage"
  20. sh "mvn test"
  21. }
  22. stage('Build') {
  23. echo "3.Build Docker Image Stage"
  24. sh "mvn package -Dmaven.test.skip=true"
  25. sh "docker build -t ${docker_img_name}:${build_tag} " +
  26. " --build-arg SPRING_PROFILE=prod " +
  27. " --build-arg JAR_FILE=target/${pom.artifactId}-${pom.version}.jar " +
  28. " ./location/"
  29. }
  30. stage('Push') {
  31. echo "4.Deploy jar and Push Docker Image Stage"
  32. sh "mvn deploy -Dmaven.test.skip=true"
  33. sh "docker tag ${docker_img_name}:${build_tag} ${docker_img_name}:latest"
  34. sh "docker tag ${docker_img_name}:${build_tag} ${docker_img_name}:${pom.version}"
  35. withCredentials([usernamePassword(credentialsId: 'docker-register', passwordVariable: 'dockerPassword', usernameVariable: 'dockerUser')]) {
  36. sh "docker login -u ${dockerUser} -p ${dockerPassword} docker.ryan-miao.com"
  37. sh "docker push ${docker_img_name}:latest"
  38. sh "docker push ${docker_img_name}:${pom.version}"
  39. sh "docker push ${docker_img_name}:${build_tag}"
  40. }
  41. }
  42. //stash 'complete-build'
  43. }
  44. if (env.BRANCH_NAME == 'master' || env.BRANCH_NAME == null) {
  45. timeout(time: 10, unit: 'MINUTES') {
  46. input '确认要部署线上环境吗?'
  47. }
  48. }
  49. node('slave001'){
  50. stage('Deploy') {
  51. //unstash 'complete-build'
  52. echo "5. Deploy Stage"
  53. sh "sed -i 's/<IMG_NAME>/${img_name}:${build_tag}/' location/k8s.yaml"
  54. sh "sed -i 's/<BRANCH_NAME>/${env.BRANCH_NAME}/' location/k8s.yaml"
  55. sh "/data/opt/kubernetes/client/bin/kubectl apply -f ${WORKSPACE}/location/k8s.yaml --record"
  56. }
  57. }
  • 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: 'location/pom.xml' 是读取workspace下相对目录的pom文件。这个需要Jenkins 安装Pipeline Utility Steps插件。通过${pom.groupId}-${pom.artifactId}来获取pom信息. 我的pom在子module location里。
  • docker_host = "docker.ryan-miao.com" 声明一个全局的变量,如果只想在方法体 {}中使用,可以加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里的凭证。这个需要安装Credentials Binding Plugin.
  • input会产生一个交互式的按钮,需要手动点击通过才会继续,否则暂停。这个只是暂停下一步,线程还在运行。所以,需要单独提出node之外,再添加一个超时设置。参见“input” step blocks executor
  • 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进行部署.

使用Jenkins pipeline流水线构建docker镜像和发布的更多相关文章

  1. 使用docker Maven插件本地构建docker镜像并发布到远程服务器

    1.登录网站https://start.spring.io/,生成一个基本的SpringBoot应用. 2.将应用导入Eclipse IDE并创建Application类.目录结构如下: Applic ...

  2. OpenShift应用镜像构建(3) - Jenkins的流水线构建

    Jenkins方式构建的定位是使用专门的CICD平台. 既支持把JenKins作为一个Pod部署到openshift内部,也支持部署在Openshift集群外部,操作上的区别是 openshift自己 ...

  3. Docker:使用Jenkins构建Docker镜像

    Docker  彭东稳  1年前 (2016-12-27)  10709次浏览  已收录  0个评论 一.介绍Jenkins Jenkins是一个开源项目,提供了一种易于使用的持续集成系统,使开发者从 ...

  4. Kubernetes DevOps: Jenkins Pipeline (流水线)

    要实现在 Jenkins 中的构建工作,可以有多种方式,我们这里采用比较常用的 Pipeline 这种方式.Pipeline,简单来说,就是一套运行在 Jenkins 上的工作流框架,将原来独立运行于 ...

  5. Jenkins+pipeline+参数构建+人工干预确定

    Jenkins+pipeline+参数构建+人工干预 实现了以下功能 1. 可以选择环境,单选:可以选择需要发布的项目,多选 2.发布过程可视化 3. 可以人工干预是否继续发布. 初始化配置需要很久, ...

  6. Maven插件构建Docker镜像

    背景 微服务架构下,微服务在带来良好的设计和架构理念的同时,也带来了运维上的额外复杂性,尤其是在服务部署和服务监控上.单体应用是集中式的,就一个单体跑在一起,部署和管理的时候非常简单,而微服务是一个网 ...

  7. jenkins自动打包生成docker镜像后自动发布并nginx代理访问

    之前曾写过docker及jenkins基础使用  https://www.cnblogs.com/xiaochangwei/category/816943.html 现在搭建环境的功能为: 1.jen ...

  8. 多阶段构建Docker镜像

    在Docker 17.05及更高的版本中支持支持一种全新的构建镜像模式:多阶段构建: 多阶段构建Docker镜像的最大好处是使构建出来的镜像变得更小: 目前常见的两个构建镜像的方式为: 1.直接使用某 ...

  9. 打包应用和构建Docker镜像(docker在windows上)

    在构建Docker时编译应用 一般有两种方法在构建镜像时进行打包应用.第一种方法就是使用基本的镜像,该镜像包括应用平台和构建工具,因此在Dockerfile中,复制源代码到镜像中并在构建镜像时编译ap ...

随机推荐

  1. 关于appium-doctor运行时提示不是内部或外部的命令

    1.一定要单独配置android_home (我之前是直接将D:\SDK\platform-tools;D:\SDK\tools;加到path里面会导致appnium-doctor运行时失败,原因为A ...

  2. Java程序员如何选择未来的职业路线

    一.程序员的特性 技术出身的职场人特性很明显,与做市场.业务出身的职场人区别尤其明显.IT行业中常见的一些职场角色:老板.项目经理.产品经理.需求分析师.设计师.开发工程师.运维工程师等.开发工程师具 ...

  3. JSP页面分页显示数据

    效果如上图所示!最多显示10条:完整jsp和后台代码如下: <%@ page contentType="text/html;charset=UTF-8" %> < ...

  4. 使用pdfBox实现pdf转图片,解决中文方块乱码等问题

    一.引入依赖 <dependency> <groupId>org.apache.pdfbox</groupId> <artifactId>fontbox ...

  5. raid 搭建

    RAID几种常见的类型 RAID类型 最低磁盘个数 空间利用率 各自的优缺点 级 别 说 明 RAID0 条带卷 2+ 100% 读写速度快,不容错 RAID1 镜像卷 2 50% 读写速度一般,容错 ...

  6. java多线程之守护线程(Daemon)

    https://blog.csdn.net/u010739551/article/details/51065923/

  7. JAVA中handleEvent和action的区别

    看代码中用到了handleEvent和action,都是对事件进行处理的,觉得这两个方法可以直接合并,于是尝试合并后,发现功能还是有问题,说明两者还是有区别了,查了很久的资料,才基本了解这两者的区别. ...

  8. Xamarin Essentials教程检查网络连通性Connectivity

    Xamarin Essentials教程检查网络连通性Connectivity   网络连通性其实就是检测当前设备有没有连接网络.网络连通性在很多与网络相关的应用程序中会使用到.在Xamarin中如果 ...

  9. [OC] @property时,copy、strong、weak、assign的区别

    @property(copy,nonatomic)NSMutableString*copyStr; @property(strong,nonatomic)NSMutableString*strongS ...

  10. loading加载动画效果js实现

    <style>.box { width: 400px; padding: 20px; border: 40px solid #a0b3d6; background-color: #eee; ...