一、声明式流水线Pipeline语法¶
声明式流水线必须包含在一个 Pipeline 块中,比如以下是一个 Pipeline 块的格式:
pipeline {
/* insert Declarative Pipeline here */
}
在声明式流水线中有效的基本语句和表达式遵循与 Groovy 的语法同样的规则,但有以下例外:
- 流水线顶层必须是一个 block,即 pipeline{};
- 分隔符可以不需要分号,但是每条语句都必须在自己的行上;
- 块只能由 Sections、Directives、Steps 或 assignment statements 组成;
- 属性引用语句被当做是无参数的方法调用,比如 input 会被当做 input()。
二、Agent¶
Agent表示整个流水线或特定阶段中的步骤和命令执行的位置,该部分必须在pipeline块的顶层被定义,也可以在 stage中再次定义,但是stage级别是可选的。
1.Agent的配置函数
为了支持可能有的各种各样的流水线,agent支持一些不同类型的参数,这些参数应用在pipeline块的顶层,或stage指令内部。agent可选配置如下:
- any:在任何可用的代理上执行流水线,配置语法:
pipeline {
agent any
}
- none:表示该Pipeline脚本没有全局的agent配置。当顶层的agent配置为none时, 每个stage部分都需要包含它自己的agent。配置语法:
pipeline {
agent none
stages {
stage('Stage For Build'){
agent any
}
}
}
- label:选择某个具体的节点执行 Pipeline 命令,例如:agent { label 'my-defined-label' }。 配置语法:
pipeline {
agent none
stages {
stage('Stage For Build') {
agent { label 'my-slave-label' }
steps {
// Add build steps here
}
}
}
}
-
node:和 label 配置类似,只不过是可以添加一些额外的配置,比如 customWorkspace;
-
dockerfile:使用从源码中包含的Dockerfile所构建的容器执行流水线或stage。为了使用该选项,Jenkinsfile必须从多个分支流水线中加载,或者从pipeline from SCM加载。如果配置的语法为agent {dockerfile true},那么将从源码的根目录下使用Dockerfile文件进行构建。如果Dockerfile文件在其他目录,则需要使用dir字段更改Dockerfile所在的目录,配置方法为agent { dockerfile { dir 'DockerfileDir'} }。如果构建镜像的Dockerfile名称不是Dockerfile,可以使用filename选项指定Dockerfile文件名。同时也可以使用additionalBuildArgs参数传递构建镜像的参数,比如agent{dockerfile{additionalBuildArgs '--build-arg version=1.0.2' } }。假如有一个项目需要使用Dockerfile类型的agent,并且Dockerfile在build目录,文件名为Dockerfile.build,构建时期望有一个version的参数。此时对应的agent写法如下:
agent {
dockerfile {
filename 'Dockerfile.build'
dir 'build'
label 'my-defined-label'
additionalBuildArgs '--build-arg version=1.0.2'
}
}
- docker:相当于dockerfile,可以直接使用docker字段指定外部镜像即可,可以省去构建的时间。比如使用 maven 镜像进行打包,同时可以指定 args:
agent {
docker {
image 'maven:3-alpine'
label 'my-defined-label'
args '-v /tmp:/tmp'
}
}
- kubernetes:Jenkins也支持使用 Kubernetes 创建Slave,也就是常说的动态Slave。配置示例如下:
agent {
kubernetes {
label podlabel
yaml """
kind: Pod
metadata:
name: jenkins-agent
spec:
containers:
- name: kaniko
image: gcr.io/kaniko-project/executor:debug
imagePullPolicy: Always
command:
- /busybox/cat
tty: true
volumeMounts:
- name: aws-secret
mountPath: /root/.aws/
- name: docker-registry-config
mountPath: /kaniko/.docker
restartPolicy: Never
volumes:
- name: aws-secret
secret:
secretName: aws-secret
- name: docker-registry-config
configMap:
name: docker-registry-config
"""
}
}
2.Agent常用选项
- label:一个字符串,该标签用于运行流水线的位置。该选项对node、docker和dockerfile可用,node必须选择该选项
- customWorkspace:一个字符串,用于自定义工作区运行流水线或stage。它可以是相对路径,也可以是绝对路径,该选项对node、docker和dockerfile可用。比如:
agent none
node {
label 'my-defined-label'
customWorkspace '/some/other/path'
}
- reuseNode:一个布尔值,默认为false。如果是true,则在同一个工作目录执行流水线。这个选项对docker和dockerfile有用,并且只有使用在个别stage的agent上才会有效。通常情况下使用docker作为agent时会开启此参数:
agent none
docker {
image 'maven:3-alpine'
label 'my-defined-label'
args '-v /tmp:/tmp'
reuseNode true
}
3.Agent配置示例
示例 1:假设有一个 Java 项目,需要用 mvn 命令进行编译,此时可以使用 maven 的镜像作 为 agent。配置如下:
Jenkinsfile (Declarative Pipeline) // 可以不要此行
pipeline {
agent { docker 'maven:3-alpine' }
stages {
stage('Example Build') {
steps {
sh 'mvn -B clean verify'
}
}
}
}
示例 2:本示例在流水线顶层将 agent 定义为 none,那么此时 stage 部分就需要必须包含它 自己的 agent 部分。在 stage('Example Build')部分使用 maven:3-alpine 执行该阶段步骤,在 stage('Example Test')部分使用 openjdk:8-jre 执行该阶段步骤。此时 Pipeline 如下:
Jenkinsfile (Declarative Pipeline)
pipeline {
agent none
stages {
stage('Example Build') {
agent { docker 'maven:3-alpine' }
steps {
echo 'Hello, Maven'
sh 'mvn --version'
}
}
stage('Example Test') {
agent { docker 'openjdk:8-jre' }
steps {
echo 'Hello, JDK'
sh 'java -version'
}
}
}
}
示例 3:上述的示例也可以用基于 Kubernetes 的 agent 实现。比如定义具有三个容器的 Pod, 分别为 jnlp(负责和 Jenkins Master 通信)、build(负责执行构建命令)、kubectl(负责执行 Kubernetes 相关命令),在 steps 中可以通过 containers 字段,选择在某个容器执行命令:
pipeline {
agent {
kubernetes {
cloud 'kubernetes-default'
slaveConnectTimeout 1200
yaml '''
apiVersion: v1
kind: Pod
spec:
containers:
- args: [\'$(JENKINS_SECRET)\', \'$(JENKINS_NAME)\']
image: 'registry.cn-beijing.aliyuncs.com/citools/jnlp:alpine'
name: jnlp
imagePullPolicy: IfNotPresent
- command:
- "cat"
image: "registry.cn-beijing.aliyuncs.com/citools/maven:3.5.3"
imagePullPolicy: "IfNotPresent"
name: "build"
tty: true
- command:
- "cat"
image: "registry.cn-beijing.aliyuncs.com/citools/kubectl:self-1.17"
imagePullPolicy: "IfNotPresent"
name: "kubectl"
tty: true
'''
}
}
stages {
stage('Building') {
steps {
container(name: 'build') {
sh """
mvn clean install
"""
}
}
}
stage('Deploy') {
steps {
container(name: 'kubectl') {
sh """
kubectl get node
"""
}
}
}
}
}