许多组织使用Docker统一其跨机器的构建和测试环境,并提供一种用于部署应用程序的有效机制。从Pipeline 2.5及更高版本开始,Pipeline内置支持从内与Docker进行交互 Jenkinsfile。

虽然本节将介绍从a到Docker的使用基础知识 Jenkinsfile,但不会涵盖Docker的基础知识,可以在Docker入门指南中进行阅读 。

定制执行环境

Pipeline旨在轻松地将 Docker 映像用作单个Stage 或整个Pipeline 的执行环境 。这意味着用户可以定义其管道所需的工具,而无需手动配置代理。几乎任何可以 打包在Docker容器中的工具。只需对进行较小的修改即可轻松使用Jenkinsfile。

Jenkinsfile(声明性管道)

pipeline { agent { docker { image 'node:7-alpine' } } stages { stage('Test') { steps { sh 'node --version' } } }}

切换脚本管道 (高级)

当管道执行时,Jenkins将自动启动指定的容器并在其中执行定义的步骤:

[Pipeline] stage[Pipeline] { (Test)[Pipeline] sh[guided-tour] Running shell script+ node --versionv7.4.0[Pipeline] }[Pipeline] // stage[Pipeline] }

缓存容器数据

许多构建工具会下载外部依赖项并将其本地缓存以供将来重用。由于容器最初是使用“干净”文件系统创建的,因此这可能会导致管道运行速度变慢,因为它们可能无法利用后续管道运行之间的磁盘缓存。

管道支持添加传递给Docker的自定义参数,从而允许用户指定 要安装的自定义 Docker卷,可用于 在两次管道运行之间在代理上缓存数据 。以下示例将~/.m2利用maven容器在两次管道运行之间进行 缓存,从而避免为管道的后续运行重新下载依赖项。

Jenkinsfile(声明性管道)

pipeline { agent { docker { image 'maven:3-alpine' args '-v $HOME/.m2:/root/.m2' } } stages { stage('Build') { steps { sh 'mvn -B' } } }}

切换脚本管道 (高级)

使用多个容器

代码库依赖于多种不同的技术变得越来越普遍。例如,存储库可能同时具有基于Java的后端API实现和基于JavaScript的前端实现。结合使用Docker和Pipeline可以通过将指令与不同阶段结合Jenkinsfile使用 多种技术agent {}。

Jenkinsfile(声明性管道)

pipeline { agent none stages { stage('Back-end') { agent { docker { image 'maven:3-alpine' } } steps { sh 'mvn --version' } } stage('Front-end') { agent { docker { image 'node:7-alpine' } } steps { sh 'node --version' } } }}

切换脚本管道 (高级)

使用Dockerfile

对于需要更多自定义执行环境的项目,Pipeline还支持从Dockerfile源存储库中构建和运行容器。与以前使用“现成”容器的方法相比,使用该agent { dockerfile true }语法Dockerfile将从Docker Hub而不是从 Docker Hub生成一个新映像。

重用上面的示例,并使用一个更自定义的示例Dockerfile:

Docker文件

FROM node:7-alpineRUN apk add -U subversion

通过将其提交到源存储库的根目录,Jenkinsfile可以将其更改为基于此构建容器Dockerfile,然后使用该容器运行定义的步骤:

Jenkinsfile(声明性管道)

pipeline { agent { dockerfile true } stages { stage('Test') { steps { sh 'node --version' sh 'svn --version' } } }}

该agent { dockerfile true }语法支持许多其他选项,这些选项将在“ 管道语法”部分中详细介绍 。

在Jenkins Pipeline中使用Dockerfile

指定Docker标签

默认情况下,管道假定任何已配置的 代理都能够运行基于Docker的管道。对于具有macOS,Windows或其他代理程序且无法运行Docker守护程序的Jenkins环境,此默认设置可能会出现问题。管道在“ 管理Jenkins”页面和“ 文件夹” 级别提供了一个全局选项,用于指定要使用哪些代理(按 Label)来运行基于Docker的管道。

脚本管道的高级用法

运行“ sidecar”容器

在管道中使用Docker是运行构建或一组测试可能依赖的服务的有效方法。与sidecar模式类似 ,Docker Pipeline可以“在后台”运行一个容器,而在另一个容器中执行工作。利用这种“边车”方法,管道可以为每个管道运行配备一个“干净”的容器。

考虑一个假设的集成测试套件,该套件依赖于要运行的本地MySQL数据库。使用withRun在Docker Pipeline插件对Scripted Pipeline的支持中实现的方法, Jenkinsfile可以将MySQL作为辅助工具运行:

node { checkout scm /* * In order to communicate with the MySQL server, this Pipeline explicitly * maps the port (`3306`) to a known port on the host machine. */ docker.image('mysql:5').withRun('-e "MYSQL_ROOT_PASSWORD=my-secret-pw" -p 3306:3306') { c -> /* Wait until mysql service is up */ sh 'while ! mysqladmin ping -h0.0.0.0 --silent; do sleep 1; done' /* Run some tests which require MySQL */ sh 'make check' }}

可以进一步利用该示例,同时使用两个容器。一个“边车”运行MySQL,另一个通过Docker 容器链接提供执行环境。

node { checkout scm docker.image('mysql:5').withRun('-e "MYSQL_ROOT_PASSWORD=my-secret-pw"') { c -> docker.image('mysql:5').inside("--link ${c.id}:db") { /* Wait until mysql service is up */ sh 'while ! mysqladmin ping -hdb --silent; do sleep 1; done' } docker.image('centos:7').inside("--link ${c.id}:db") { /* * Run some tests which require MySQL, and assume that it is * available on the host name `db` */ sh 'make check' } }}

上面的示例使用暴露的对象withRun,该对象具有通过id属性提供的运行容器的ID 。通过使用容器的ID,管道可以通过将自定义Docker参数传递给inside()方法来创建链接 。

该id属性对于在管道退出之前检查正在运行的Docker容器中的日志也很有用:

sh "docker logs ${c.id}"

建筑容器

为了创建Docker映像,Docker Pipeline 插件还提供了build()一种Dockerfile在Pipeline运行期间从存储库中的创建新映像的方法 。

使用该语法的一个主要好处docker.build("my-image-name")是,脚本化管道可以将返回值用于后续的Docker Pipeline调用,例如:

node { checkout scm def customImage = docker.build("my-image:${env.BUILD_ID}") customImage.inside { sh 'make test' }}

返回值还可以用于通过以下方法将Docker映像发布到 Docker Hub或自定义注册表,push()例如:

node { checkout scm def customImage = docker.build("my-image:${env.BUILD_ID}") customImage.push()}

映像“标签”的一种常见用法是为latest最新,经过验证的Docker映像版本指定标签。该push()方法接受一个可选tag参数,允许管道customImage使用不同的标签推送,例如:

node { checkout scm def customImage = docker.build("my-image:${env.BUILD_ID}") customImage.push() customImage.push('latest')}

该build()方法Dockerfile默认在当前目录中构建。可以通过提供包含路径Dockerfile作为方法的第二个参数的目录路径来覆盖它build(),例如:

node { checkout scm def testImage = docker.build("test-image", "./dockerfiles/test")  testImage.inside { sh 'make test' }}

test-image根据位于的Dockerfile 构建./dockerfiles/test/Dockerfile。

通过将其他参数 添加到方法的第二个参数中,可以将其他参数传递给 docker buildbuild()。以这种方式传递参数时,该字符串中的最后一个值必须是docker文件的路径,并且应以文件夹结尾作为构建上下文)

本示例Dockerfile通过传递-f 标志来覆盖默认值:

node { checkout scm def dockerfile = 'Dockerfile.test' def customImage = docker.build("my-image:${env.BUILD_ID}", "-f ${dockerfile} ./dockerfiles") }

my-image:${env.BUILD_ID}根据位于的Dockerfile 构建./dockerfiles/Dockerfile.test。

使用远程Docker服务器

默认情况下,Docker Pipeline插件将与本地Docker守护进程通信,该守护进程通常通过访问/var/run/docker.sock。

要选择非默认的Docker服务器,例如 Docker Swarm,withServer()应使用该方法。

通过使用以下方法将URI以及可选的Jenkins中预先配置的Docker服务器证书身份验证的凭据ID传递给方法:

node { checkout scm docker.withServer('tcp://swarm.example.com:2376', 'swarm-certs') { docker.image('mysql:5').withRun('-p 3306:3306') { /* do things */ } }}

inside()并build()不会与码头工人群服务器正常工作,开箱即用

为了inside()正常工作,Docker服务器和Jenkins代理必须使用相同的文件系统,以便可以安装工作空间。

当前,Jenkins插件和Docker CLI都不会自动检测服务器正在远程运行的情况。典型的症状是嵌套sh命令的错误,例如

cannot create /…@tmp/durable-…/pid: Directory nonexistent

当詹金斯(Jenkins)检测到代理本身在Docker容器中运行时,它将自动将--volumes-from参数传递给 inside容器,以确保它可以与代理共享工作区。

此外,某些版本的Docker Swarm不支持​​自定义注册表。

使用自定义注册表

默认情况下,Docker Pipeline集成假定Docker Hub为默认的Docker Registry 。

为了使用自定义Docker注册表,脚本化管道的用户可以使用withRegistry()方法包装步骤,并传入自定义注册表URL,例如:

node { checkout scm docker.withRegistry('https://registry.example.com') { docker.image('my-custom-image').inside { sh 'make test' } }}

对于需要身份验证的Docker注册表,请从Jenkins主页添加“用户名/密码”凭据项,并将凭据ID作为第二个参数使用withRegistry():

node { checkout scm docker.withRegistry('https://registry.example.com', 'credentials-id') { def customImage = docker.build("my-image:${env.BUILD_ID}") /* Push the container to the custom Registry */ customImage.push() }}

将两个文件的路径作为参数传递给脚本_将Docker与pipeline一起使用相关推荐

  1. java两个文件夹比较路径_比较Java中两个文件的路径

    java两个文件夹比较路径 Given the paths of the two files and we have two compare the paths of the files in Jav ...

  2. php算出文件相对路径,php计算两个文件相对路径的方法

    本文实例讲述了php计算两个文件相对路径的方法.分享给大家供大家参考.具体如下: 一.问题: 写一个php函数算出两个文件的相对路径.例如$a="/a/b/c/d/e.php"; ...

  3. python文件比较,判断两个文件是否相同

    # 判断两个文件是否相同.要求用函数实现文件比较功能,在main函数中进行验证. # 下述函数完成文件是否相同的比较功能 def compareFile(file1,file2):#请在此添加代码,实 ...

  4. php源码之计算两个文件的相对路径

    <?php //计算出两个文件的相对路径即path2相对于$path1的相对路径 // http://www.manongjc.com/article/1342.html function ge ...

  5. 从命令行获取两个路径名称并找出文件一样内容一样的两个文件

    import os import sys import subprocess import hashlibdir1 = sys.argv[1] dir2 = sys.argv[2]class File ...

  6. 一道PHP面试题,求两个文件的相对路径

    2019独角兽企业重金招聘Python工程师标准>>> 首先原题是这样子的: 写一个函数,计算出两个文件的相对路径,如 $a = '/a/b/c/d/d.php',$b = '/a/ ...

  7. 更好地整理数据:windows下怎么让不同路径下的两个文件夹保持同步内容

    目录 1.使用"同步工具"软件 2.使用Robocopy命令 3.Robocopy的一个小例子 4.自动复制 4.1打开任务计划程序 4.2 创建任务 4.3 设置触发器 4.4 ...

  8. 求两个文件的相对路径

    A:例子 写一个函数,计算出两个文件的相对路径,如 $a = '/a/b/c/d/d.php',$b = '/a/b/1/2/c.php' 计算出的$b相对于$a的相对路径应该是:../../c/d ...

  9. Java如何校验两个文件内容是相同的?

    欢迎关注方志朋的博客,回复"666"获面试宝典 今天做文件上传功能,需求要求文件内容相同的不能重复上传.感觉这个需求挺简单的就交给了一位刚入行的新同学.等合并代码的时候发现这位同学 ...

最新文章

  1. 【想象不到的俄罗斯】……太震撼了……
  2. Kafka实现MySQL增量同步
  3. VC实现最小化后在系统托盘显示
  4. 《FPGA入门教程》看书随笔——RTL设计
  5. 【SDOI2014】数表【莫比乌斯反演】【树状数组】
  6. win7桌面计算机没了,win7系统桌面的计算机图标没了的解决方法
  7. 口琴膜片什么作用_新手怎么学口琴?
  8. azure 安全组_具有安全性和设计注意事项的Azure成本跟踪
  9. 20190806:字符串解密
  10. Python npy文件
  11. 语音和音乐信号中的预加重处理
  12. 当前流行的J2EE WEB应用架构分析(一)
  13. 转:大前研一:“质问力”是解决问题最重要的能力
  14. TP6.0 一对一模型关联 hasOne
  15. 人民币换算美元java计算_美元和人民币换算(人民币转换美元计算)
  16. gnu stubs arch linux,编译Nachos源代码时出现错误“gnu/stubs-32.h:No such file or directory”...
  17. Mac:当iPhone连接苹果电脑时,自动弹出照片的解决方案
  18. 计算机认知矫正发展史,计算机认知矫正疗法对儿童认知功能的影响.pdf
  19. Android百度地图无法定位问题
  20. Yolo系列检测网络不再孤单,延伸框架层出不穷(附框架源代码)

热门文章

  1. [第1节]时间、空间复杂度,斐波那契、爬楼梯
  2. Android 制定安装重写迁移至SD卡 APP2SD
  3. 日志输出到文件nacos 配置_python 配置日志输出到终端与文件
  4. Android/Linux线程死锁demo分析
  5. popToRootViewController & popToViewController
  6. 解决This application failed to start because cannot find or load the qt platform plugin 'xcb'
  7. Windows与Linux下查看占用端口的进程
  8. oracle+快速客户端安装方法,ORACLE简易客户端安装与使用方法
  9. 反射创建对象_面试题汇集——java反射
  10. 编译原理---NFA转化为DFA---DFA最小化(自己看)