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

许多组织使用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() }}
54ffd5302e3cc1bc4e39450897f75d7e.png
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值