5.4. Pipeline 构建
Pipeline 构建策略在 OpenShift Container Platform 4 中弃用。基于 Tekton 的 OpenShift Pipelines 中带有等效且改进的功能。
OpenShift 上的 Jenkins 镜像被完全支持,用户可以按照 Jenkins 用户文档在作业中定义 Jenkinsfile,或者将其存储在 Source Control Management 系统中。
采用 Pipeline 构建策略时,开发人员可以定义由 Jenkins Pipeline 插件执行的 Jenkins Pipeline。构建可以由 OpenShift Container Platform 启动、监控和管理,其方式与任何其他构建类型相同。
Pipeline 工作流在 Jenkinsfile 中定义,或直接嵌入在构建配置中,或者在 Git 存储库中提供并由构建配置引用。
5.4.1. 了解 OpenShift Container Platform 管道
通过管道(pipeline),您可以控制在 OpenShift Container Platform 上构建、部署和推进您的应用程序。通过结合使用 Jenkins Pipeline 构建策略、Jenkinsfile 和 OpenShift Container Platform 域特定语言 (DSL)(由 Jenkins 客户端插件提供),您可以为任何场景创建高级构建、测试、部署和推进管道。
OpenShift Container Platform Jenkins 同步插件
OpenShift Container Platform Jenkins 同步插件使 BuildConfig
和 Build 对象与 Jenkins 任务和构建保持同步,并提供以下功能:
- Jenkins 中动态创建任务/运行。
- 从 ImageStreams、ImageStreamTag 或 ConfigMap 动态创建 slave Pod 模板。
- 注入环境变量。
- OpenShift web 控制台中的管道视觉化。
- 与 Jenkins Git 插件集成,后者传递提交信息
- 将 secret 同步到 OpenShift 为 Jenkins Git 插件构建的 Jenkins 凭证条目。
OpenShift Container Platform Jenkins 客户端插件
OpenShift Container Platform Jenkins 客户端插件是一种 Jenkins 插件,旨在提供易读、简洁、全面且流畅的 Jenkins Pipeline 语法,以便与 OpenShift Container Platform API 服务器进行丰富的交互。该插件利用了 OpenShift 命令行工具 (oc
),此工具必须在执行脚本的节点上可用。
Jenkins 客户端插件必须安装到 Jenkins master上,这样才能在您的应用程序的 JenkinsFile 中使用 OpenShift Container Platform DSL。使用 OpenShift Container Platform Jenkins 镜像时,默认安装并启用此插件。
对于项目中的 OpenShift Container Platform 管道,必须使用 Jenkins Pipeline 构建策略。此策略默认使用源存储库根目录下的 jenkinsfile
,但也提供以下配置选项:
-
BuildConfig
中的内联jenkinsfile
字段。 -
BuildConfig
中的jenkinsfilePath
字段,该字段引用要使用的jenkinsfile
的位置,路径相对于源contextDir
。
可选的 jenkinsfilePath
字段指定要使用的文件的名称,其路径相对于源 contextDir
。如果省略了 contextDir
,则默认为存储库的根目录。如果省略了 jenkinsfilePath
,则默认为 jenkinsfile
。
5.4.2. 为 Pipeline 构建提供 Jenkinsfile
jenkinsfile
使用标准的 Groovy 语言语法,允许对应用程序的配置、构建和部署进行精细控制。
您可以通过以下一种方式提供 jenkinsfile
:
- 位于源代码存储库中的文件。
-
使用
jenkinsfile
字段嵌入为构建配置的一部分。
使用第一个选项时,jenkinsfile
必须包含在以下位置之一的应用程序源代码存储库中:
-
存储库根目录下名为
jenkinsfile
的文件。 -
存储库的源
contextDir
的根目录下名为jenkinsfile
的文件。 -
通过 BuildConfig 的
JenkinsPipelineStrategy
部分的jenkinsfilePath
字段指定的文件名;若提供,则路径相对于源contextDir
,否则默认为存储库的根目录。
jenkinsfile
在 Jenkins slave Pod 上执行,如果您打算使用 OpenShift DSL,它必须具有 OpenShift Client 二进制文件。
流程
若要提供 Jenkinsfile,您可以执行以下操作之一:
- 在构建配置中嵌入 Jenkinsfile。
- 在构建配置中包含对含有 Jenkinsfile 的 Git 存储库的引用。
嵌入式定义
kind: "BuildConfig" apiVersion: "v1" metadata: name: "sample-pipeline" spec: strategy: jenkinsPipelineStrategy: jenkinsfile: |- node('agent') { stage 'build' openshiftBuild(buildConfig: 'ruby-sample-build', showBuildLogs: 'true') stage 'deploy' openshiftDeploy(deploymentConfig: 'frontend') }
引用 Git 存储库
kind: "BuildConfig"
apiVersion: "v1"
metadata:
name: "sample-pipeline"
spec:
source:
git:
uri: "https://github.com/openshift/ruby-hello-world"
strategy:
jenkinsPipelineStrategy:
jenkinsfilePath: some/repo/dir/filename 1
- 1
- 可选的
jenkinsfilePath
字段指定要使用的文件的名称,其路径相对于源contextDir
。如果省略了contextDir
,则默认为存储库的根目录。如果省略了jenkinsfilePath
,则默认为 Jenkinsfile。
5.4.3. 使用环境变量进行 Pipeline 构建
要将环境变量提供给 Pipeline 构建过程使用,您可以在 BuildConfig
的 jenkinsPipelineStrategy
定义中添加环境变量。
定义之后,环境变量将设置为与 BuildConfig
关联的任何 Jenkins 任务的参数。
流程
定义要在构建期间使用的环境变量:
jenkinsPipelineStrategy: ... env: - name: "FOO" value: "BAR"
您也可以使用 oc set env
命令管理 BuildConfig
中定义的环境变量。
5.4.3.1. BuildConfig 环境变量和 Jenkins 任务参数之间的映射
基于对 Pipeline 策略的 BuildConfig
的更改创建或更新 Jenkins 任务时,BuildConfig
中的任何环境变量都会映射到 Jenkins 任务参数定义,其中 Jenkins 任务参数定义的默认值是相关联的环境变量的当前值。
在 Jenkins 任务初始创建之后,您仍然可以从 Jenkins 控制台向任务添加其他参数。参数名称与 BuildConfig
中的环境变量名称不同。为这些 Jenkins 任务启动构建时,将遵循这些参数。
为 Jenkins 任务启动构建的方式决定了如何设置参数。
-
如果使用
oc start-build
启动,则BuildConfig
中环境变量的值是为对应任务实例设置的参数。您在 Jenkins 控制台中对参数默认值所做的更改都将被忽略。BuildConfig
值具有优先权。 如果使用
oc start-build -e
启动,则-e
选项中指定的环境变量值具有优先权。-
如果指定没有列在
BuildConfig
中的环境变量,它们会添加为 Jenkins 任务参数定义。 -
您在 Jenkins 控制台中对与环境变量对应的参数所做的更改都将被忽略。
BuildConfig
以及您通过oc start-build -e
指定的值将具有优先权。
-
如果指定没有列在
- 如果使用 Jenkins 控制台启动 Jenkins 任务,您可以使用 Jenkins 控制台控制参数的设置,作为启动任务构建的一部分。
建议您在 BuildConfig
中指定与任务参数关联的所有可能环境变量。这样做可以减少磁盘 I/O 并提高 Jenkins 处理期间的性能。
5.4.4. Pipeline 构建教程
本例演示如何创建 OpenShift Pipeline,以使用 nodejs-mongodb.json
模板构建、部署和验证 Node.js/MongoDB
应用程序。
流程
创建 Jenkins master:
$ oc project <project_name> 1 $ oc new-app jenkins-ephemeral 2
使用以下内容,创建名为 nodejs-sample-pipeline.yaml 的文件:
注意这将创建一个
BuildConfig
,它将使用 Jenkins Pipeline 策略来构建、部署和扩展Node.js/MongoDB
示例应用程序。kind: "BuildConfig" apiVersion: "v1" metadata: name: "nodejs-sample-pipeline" spec: strategy: jenkinsPipelineStrategy: jenkinsfile: <pipeline content from below> type: JenkinsPipeline
使用
jenkinsPipelineStrategy
创建BuildConfig
后,请通过使用内联jenkinsfile
告知管道接下来做什么:注意本例没有为应用程序设置 Git 存储库。
以下
jenkinsfile
内容使用 OpenShift DSL 以 Groovy 语言编写。在本例中,请使用 YAML Literal Style 在BuildConfig
中包含内联内容,但首选的方法是使用源存储库中的jenkinsfile
。def templatePath = 'https://raw.githubusercontent.com/openshift/nodejs-ex/master/openshift/templates/nodejs-mongodb.json' 1 def templateName = 'nodejs-mongodb-example' 2 pipeline { agent { node { label 'nodejs' 3 } } options { timeout(time: 20, unit: 'MINUTES') 4 } stages { stage('preamble') { steps { script { openshift.withCluster() { openshift.withProject() { echo "Using project: ${openshift.project()}" } } } } } stage('cleanup') { steps { script { openshift.withCluster() { openshift.withProject() { openshift.selector("all", [ template : templateName ]).delete() 5 if (openshift.selector("secrets", templateName).exists()) { 6 openshift.selector("secrets", templateName).delete() } } } } } } stage('create') { steps { script { openshift.withCluster() { openshift.withProject() { openshift.newApp(templatePath) 7 } } } } } stage('build') { steps { script { openshift.withCluster() { openshift.withProject() { def builds = openshift.selector("bc", templateName).related('builds') timeout(5) { 8 builds.untilEach(1) { return (it.object().status.phase == "Complete") } } } } } } } stage('deploy') { steps { script { openshift.withCluster() { openshift.withProject() { def rm = openshift.selector("dc", templateName).rollout() timeout(5) { 9 openshift.selector("dc", templateName).related('pods').untilEach(1) { return (it.object().status.phase == "Running") } } } } } } } stage('tag') { steps { script { openshift.withCluster() { openshift.withProject() { openshift.tag("${templateName}:latest", "${templateName}-staging:latest") 10 } } } } } } }
- 1
- 要使用的模板的路径。
- 2
- 要创建的模板的名称。
- 3
- 启动
node.js
slave Pod,以运行此构建。 - 4
- 为此管道设置 20 分钟超时。
- 5
- 使用此模板标签删除所有内容。
- 6
- 使用此模板标签删除任何 secret。
- 7
- 从
templatePath
创建一个新应用程序。 - 8
- 等待最多五分钟以完成构建。
- 9
- 等待最多五分钟以完成部署。
- 10
- 如果其余部分都成功,则将
$ {templateName}:latest
镜像标记为$ {templateName}-staging:latest
。stage 环境的管道BuildConfig
可以监控$ {templateName}-staging:latest
镜像更改,并将它部署到 stage 环境中。
注意上例使用 declarative pipeline 风格编写,但较旧的 scripted pipeline 风格也受到支持。
在 OpenShift 集群中创建管道
BuildConfig
:$ oc create -f nodejs-sample-pipeline.yaml
如果您不想自行创建文件,可以通过运行以下命令来使用 Origin 存储库中的示例:
$ oc create -f https://raw.githubusercontent.com/openshift/origin/master/examples/jenkins/pipeline/nodejs-sample-pipeline.yaml
启动管道:
$ oc start-build nodejs-sample-pipeline
注意此外,也可以通过 OpenShift Web 控制台启动管道,方法是导航到 Builds
Pipeline 部分并点击 Start Pipeline,或者访问 Jenkins 控制台,再导航到您创建的管道并点击 Build Now。 管道启动之后,您应该看到项目中执行了以下操作:
- 在 Jenkins 服务器上创建了作业实例。
- 启动了 slave Pod(如果管道需要)。
管道在 slave Pod 上运行;如果不需要 slave,则管道在 master上运行。
-
将删除之前创建的具有
template=nodejs-mongodb-example
标签的所有资源。 -
从
nodejs-mongodb-example
模板创建一个新应用程序及其所有相关资源。 使用
nodejs-mongodb-example
BuildConfig
启动构建。- 管道将等待到构建完成后触发下一阶段。
使用
nodejs-mongodb-example
部署配置启动部署。- 管道将等待到部署完成后触发下一阶段。
-
如果构建和部署都成功,则
nodejs-mongodb-example:latest
镜像将标记为nodejs-mongodb-example:stage
。
-
将删除之前创建的具有
slave Pod(如果管道过去需要)被删除。
注意视觉化管道执行的最佳方法是在 OpenShift Web 控制台中查看它。您可以通过登录 Web 控制台并导航到 Builds
Pipelines 来查看管道。