pipelien job的分布式构建(在指定的静态agent上执行任务)
agent配置段语法介绍
声明式Pipeline使用agent指定运行Job的目标节点
agent可接受多种形式的参数
◼ any:任何可用节点
◼ none:用于pipeline顶端时表示不定义默认的agent,这就需要为每个stage单独指定
◼ label { label "<label>" }:具有指定的标签的节点均为可用节点
◼ node { label "<label>" }:与label相似,但可以指定额外的参数customWorkspace
◼ docker:在指定的容器中运行pipeline或stage代码,该容器动态创建并运行于预配置的可运行容器的node上,或能够匹配到指定label的node上;可用参数如下
◆ image、label、args、rgistryUrl和registryCredentialsId
◼ dockerfile:功能上类似于上面docker参数,但容器镜像通过指定的docker进行构建;该参数要求Jenkinsfile必须从Multibranch Pipeline或者Pipeline from SCM中加载;可用参数如下
◆ filename、dir、label、additionalBuildArgs、args、registryUrl和registryCredentialsId
◼ kubernetes:于Kubernetes集群上指定的Pod中运行stage或pipeline代码,该参数同样要求Jenkinsfile必须从Multibranch Pipeline或者Pipeline from SCM中加载
◆ 需要在kubernetes参数中指定Pod模板
参考: https://www.jenkins.io/doc/book/pipeline/syntax/
在pipeline中可使用agent指令显式为Job指定执行位置,使用“label”表达式来过滤具有指定标签的节点
添加agent有两种方式:
一,在节点上直接运行;二,通过容器的方式来定义agent。
如果agent在添加到当前控制器时,本身以容器方式运行,里面不会有docker命令,因此此容器完成不了镜像的构建
所以,不依赖docker命令的步骤,调到容器的agent来运行,把需要依赖docker命令的步骤调到master上运行
具体示例如下:测试在指定的agent上执行任务
一:在jenkins上创建两个静态agent节点(创建的agent名称、远程目录要与dockerfile中的一致)
第一个节点:


启动方式:通过Java Web启动代理

第二个节点:复制第一个节点生成第二个节点


打开系统配置,全局安全配置,开启50000端口

打开节点,把密钥复制下来,替换docker-compose里面的密钥

agrnt01和agent02都需要更换
vim docker-compose-inbound-agent.yml
JENKINS_SECRET: 322a1411c1758089607bbd10e5eb587004a2cc9dad33be69cae225f67f1c391b
JENKINS_SECRET: f4e139e7084f786b3e95b2cc43a2c85e4c66778f6d0d8b8232021c1d52f95e11
让当前主机对域名进行解析
vim /etc/hosts
10.0.0.101 jenkins.magedu.com
docker-compose-inbound-agent.yml 文件
cat docker-compose-inbound-agent.yml version: '3.6'
volumes:
agent01_data: {}
agent02_data: {}
networks:
jenkins_net:
driver: bridge
ipam:
config:
- subnet: 172.31.9.0/24
services:
agent01:
image: jenkins/inbound-agent:alpine-jdk11
hostname: agent01.magedu.com
user: root
environment:
TZ: Asia/Shanghai
JENKINS_URL: http://jenkins.magedu.com:8080
JENKINS_AGENT_NAME: agent01.magedu.com
JENKINS_AGENT_WORKDIR: /home/jenkins/agent
JENKINS_SECRET: 322a1411c1758089607bbd10e5eb587004a2cc9dad33be69cae225f67f1c391b
# SECRET is automatically generated by the master when adding agent01.
volumes:
- agent01_data:/appdata/jenkins/
networks:
jenkins_net:
ipv4_address: 172.31.9.11
aliases:
- slave01
- agent01
#extra_hosts:
# - "jenkins.magedu.com:172.29.7.7" #使用域名对当前宿主机进行解析
#restart: always
agent02:
image: jenkins/inbound-agent:alpine-jdk11
hostname: agent02.magedu.com
user: root
environment:
TZ: Asia/Shanghai
JENKINS_URL: http://jenkins.magedu.com:8080
JENKINS_AGENT_NAME: agent02.magedu.com
JENKINS_AGENT_WORKDIR: /home/jenkins/agent
JENKINS_SECRET: f4e139e7084f786b3e95b2cc43a2c85e4c66778f6d0d8b8232021c1d52f95e11
# SECRET is automatically generated by the master when adding agent02.
volumes:
- agent02_data:/appdata/jenkins/
networks:
jenkins_net:
ipv4_address: 172.31.9.12
aliases:
- slave02
- agent02
#extra_hosts:
# - "jenkins.magedu.com:172.29.7.7"
#restart: always
使用docker命令启动该文件
[root@ubuntu2004 07-jenkins-agents]#docker-compose -f docker-compose-inbound-agent.yml up
去jenkins的master上查看agent01、02状态

给主节点master设置标签

声明式语法配置作业执行步骤如下:
示例限定为默认在两个静态docker容器运行的agent上进行运行,但打镜像推送镜像步骤在master上运行。
pipeline {
agent { label 'linux-jnlp-agent' } #与agent定义标签一致
parameters {
booleanParam(name:'pushImage', defaultValue: 'true', description: 'Push Image to Harbor?')
}
tools {
maven 'maven-3.8.7'
}
triggers {
GenericTrigger(
genericVariables: [
[key: 'ref', value: '$.ref']
],
token: 'fClZ0e/kTcqL2ARh7YqxW/3ndOCZA2SqfKnRTLat',
causeString: 'Triggered on $ref',
printContributedVariables: true,
printPostContent: true
)
}
environment {
codeRepo="http://gitlab.mengfanchao.com/root/spring-boot-helloWorld.git"
harborServer='harbor.meng.org'
projectName='spring-boot-helloworld'
imageUrl="${harborServer}/ikubernetes/${projectName}"
imageTag='latest'
}
stages {
stage('Source') {
steps {
git branch: 'main', credentialsId: 'gitlab-root-credential', url: "${codeRepo}"
}
}
stage('Build') {
steps {
sh 'mvn -B -DskipTests clean package'
}
}
stage('Test') {
steps {
sh 'mvn test'
}
}
stage("SonarQube Analysis") {
steps {
withSonarQubeEnv('SonarQube-Server') {
sh 'mvn sonar:sonar'
}
}
}
stage("Quality Gate") {
steps {
timeout(time: 30, unit: 'MINUTES') {
waitForQualityGate abortPipeline: true
}
}
}
stage('Build Docker Image') {
agent { label 'master' }
steps {
sh 'docker image build . -t "${harborServer}/ikubernetes/${projectName}:${imageTag}"'
}
}
stage('Push Docker Image') {
agent { label 'master' }
when {
expression { params.pushImage }
beforeAgent true #提前评估代码,通过了在去master上完成镜像推送
steps {
withCredentials([usernamePassword(credentialsId: 'harbor-user-credential', \
passwordVariable: 'harborUserPassword', usernameVariable: 'harborUserName')]) {
sh "echo ${harborUserPassword} | docker login -u ${env.harborUserName} --password-stdin ${harborServer}"
sh "docker image push ${imageUrl}:${imageTag}"
}
}
}
}
post {
always {
mail to: '1153454651@qq.com',
subject: "Status of pipeline: ${currentBuild.fullDisplayName}",
body: "${env.BUILD_URL} has result ${currentBuild.result}"
}
}
}
立即构建
