分布式构建 #
分布式构建是Jenkins的核心特性之一,通过将构建任务分发到多个节点,可以显著提高构建效率和系统扩展性。
为什么需要分布式构建? #
单节点限制 #
- 构建队列等待时间长
- 资源竞争导致效率低下
- 单点故障风险
- 无法满足多样化环境需求
分布式优势 #
- 并行构建提高效率
- 资源隔离和专业化
- 高可用性
- 灵活扩展
架构模式 #
Master-Agent架构 #
text
┌─────────────────┐
│ Jenkins Master │
│ │
│ - 调度任务 │
│ - 管理配置 │
│ - 处理请求 │
└────────┬────────┘
│
┌────────────────────┼────────────────────┐
│ │ │
▼ ▼ ▼
┌───────────────┐ ┌───────────────┐ ┌───────────────┐
│ Agent 1 │ │ Agent 2 │ │ Agent 3 │
│ (Linux) │ │ (Windows) │ │ (macOS) │
│ │ │ │ │ │
│ - Maven构建 │ │ - .NET构建 │ │ - iOS构建 │
│ - Docker │ │ - IIS部署 │ │ - Xcode │
└───────────────┘ └───────────────┘ └───────────────┘
职责分离 #
| 组件 | 职责 |
|---|---|
| Master | 任务调度、配置管理、用户界面、插件管理 |
| Agent | 执行构建、运行测试、部署应用 |
配置分布式构建 #
1. 配置Master #
禁用Master构建:
- 进入 Manage Jenkins → System
- 设置 # of executors 为 0
2. 添加Agent #
SSH Agent:
text
Name: linux-agent-01
Remote root directory: /home/jenkins/agent
Labels: linux docker maven
Launch method: Launch agents via SSH
Host: 192.168.1.100
Credentials: jenkins-ssh-key
JNLP Agent:
text
Name: windows-agent-01
Remote root directory: C:\jenkins\agent
Labels: windows dotnet
Launch method: Launch agent via Java Web Start
3. 配置标签 #
text
Agent 1: linux, docker, maven, java11
Agent 2: linux, docker, nodejs, angular
Agent 3: windows, dotnet, iis
Agent 4: macos, xcode, ios
任务调度策略 #
标签调度 #
groovy
pipeline {
agent { label 'linux && docker' }
stages {
stage('Build') {
steps {
sh 'docker build -t myapp .'
}
}
}
}
动态调度 #
groovy
pipeline {
agent none
stages {
stage('Build') {
parallel {
stage('Linux') {
agent { label 'linux' }
steps {
sh 'build-linux.sh'
}
}
stage('Windows') {
agent { label 'windows' }
steps {
bat 'build-windows.bat'
}
}
stage('macOS') {
agent { label 'macos' }
steps {
sh 'build-macos.sh'
}
}
}
}
}
}
表达式调度 #
groovy
pipeline {
agent {
label 'linux && docker && !windows'
}
stages {
stage('Build') {
steps {
sh 'docker build -t myapp .'
}
}
}
}
负载均衡 #
轮询调度 #
Jenkins默认使用轮询调度:
text
任务1 → Agent 1
任务2 → Agent 2
任务3 → Agent 3
任务4 → Agent 1
...
基于负载调度 #
groovy
options {
retry(3)
timeout(time: 30, unit: 'MINUTES')
}
自定义调度 #
groovy
def selectAgent(String label) {
def nodes = jenkins.model.Jenkins.instance.nodes
def candidates = nodes.findAll { node ->
node.labelString.contains(label) &&
node.toComputer().online &&
node.toComputer().countBusy() < node.numExecutors
}
if (candidates.isEmpty()) {
error "No available agent with label: ${label}"
}
return candidates.min { it.toComputer().countBusy() }.name
}
pipeline {
agent { label selectAgent('linux') }
stages {
stage('Build') {
steps {
echo "Building on ${NODE_NAME}"
}
}
}
}
高可用配置 #
多Agent冗余 #
text
Agent组: linux-build
├── linux-agent-01 (4 executors)
├── linux-agent-02 (4 executors)
└── linux-agent-03 (4 executors)
使用相同标签:
text
linux-agent-01: Labels: linux-build
linux-agent-02: Labels: linux-build
linux-agent-03: Labels: linux-build
故障转移 #
groovy
pipeline {
agent { label 'linux-build' }
options {
retry(3)
timeout(time: 30, unit: 'MINUTES')
}
stages {
stage('Build') {
steps {
sh 'mvn clean package'
}
}
}
}
容器化Agent #
Docker Agent #
groovy
pipeline {
agent {
docker {
image 'maven:3.8-openjdk-11'
args '-v $HOME/.m2:/root/.m2'
}
}
stages {
stage('Build') {
steps {
sh 'mvn clean package'
}
}
}
}
Kubernetes Agent #
groovy
pipeline {
agent {
kubernetes {
yaml '''
apiVersion: v1
kind: Pod
spec:
containers:
- name: maven
image: maven:3.8-openjdk-11
command: ["cat"]
tty: true
- name: docker
image: docker:latest
command: ["cat"]
tty: true
volumeMounts:
- name: docker-sock
mountPath: /var/run/docker.sock
volumes:
- name: docker-sock
hostPath:
path: /var/run/docker.sock
'''
}
}
stages {
stage('Build') {
steps {
container('maven') {
sh 'mvn clean package'
}
}
}
stage('Docker') {
steps {
container('docker') {
sh 'docker build -t myapp .'
}
}
}
}
}
跨平台构建 #
多平台矩阵 #
groovy
pipeline {
agent none
matrix {
axes {
axis {
name 'OS'
values 'linux', 'windows', 'macos'
}
axis {
name 'JAVA_VERSION'
values '8', '11', '17'
}
}
stages {
stage('Build') {
agent { label "${OS}" }
tools {
jdk "JDK ${JAVA_VERSION}"
}
steps {
script {
if (OS == 'windows') {
bat 'mvn clean package'
} else {
sh 'mvn clean package'
}
}
}
}
stage('Test') {
steps {
script {
if (OS == 'windows') {
bat 'mvn test'
} else {
sh 'mvn test'
}
}
}
}
}
}
}
资源管理 #
资源锁定 #
groovy
pipeline {
agent any
stages {
stage('Deploy') {
steps {
lock(resource: 'production-server', quantity: 1) {
sh 'deploy.sh'
}
}
}
}
}
并发控制 #
groovy
pipeline {
agent any
options {
disableConcurrentBuilds()
}
stages {
stage('Deploy') {
steps {
sh 'deploy.sh'
}
}
}
}
监控和诊断 #
节点状态 #
groovy
def checkNodes() {
def nodes = jenkins.model.Jenkins.instance.nodes
nodes.each { node ->
def computer = node.toComputer()
println "Node: ${node.name}"
println " Online: ${computer.online}"
println " Offline: ${computer.offline}"
println " Executors: ${node.numExecutors}"
println " Busy: ${computer.countBusy()}"
println " Idle: ${computer.countIdle()}"
}
}
构建时间分析 #
groovy
pipeline {
agent any
stages {
stage('Build') {
steps {
script {
def start = System.currentTimeMillis()
sh 'mvn clean package'
def duration = System.currentTimeMillis() - start
echo "Build duration: ${duration}ms"
}
}
}
}
}
最佳实践 #
1. 专用Agent #
text
build-agent: 专门用于编译
test-agent: 专门用于测试
deploy-agent: 专门用于部署
2. 资源隔离 #
text
high-memory: 大内存任务
gpu: GPU任务
ssd: 高IO任务
3. 环境隔离 #
text
dev-agent: 开发环境
staging-agent: 预发布环境
prod-agent: 生产环境
4. 自动扩缩容 #
使用Kubernetes实现自动扩缩容:
groovy
pipeline {
agent {
kubernetes {
yaml '''
apiVersion: v1
kind: Pod
spec:
containers:
- name: maven
image: maven:3.8-openjdk-11
resources:
requests:
memory: "2Gi"
cpu: "1"
limits:
memory: "4Gi"
cpu: "2"
'''
}
}
stages {
stage('Build') {
steps {
sh 'mvn clean package'
}
}
}
}
完整示例 #
groovy
pipeline {
agent none
environment {
APP_NAME = 'myapp'
VERSION = "${BUILD_NUMBER}"
}
stages {
stage('Build') {
parallel {
stage('Backend') {
agent {
docker {
image 'maven:3.8-openjdk-11'
label 'docker'
}
}
steps {
sh 'mvn clean package -DskipTests'
stash includes: 'target/*.jar', name: 'backend'
}
}
stage('Frontend') {
agent {
docker {
image 'node:18'
label 'docker'
}
}
steps {
sh 'npm ci'
sh 'npm run build'
stash includes: 'dist/**', name: 'frontend'
}
}
}
}
stage('Test') {
parallel {
stage('Unit Tests') {
agent { label 'linux && test' }
steps {
unstash 'backend'
sh 'mvn test'
}
post {
always {
junit '**/target/surefire-reports/*.xml'
}
}
}
stage('Integration Tests') {
agent {
kubernetes {
yaml '''
apiVersion: v1
kind: Pod
spec:
containers:
- name: maven
image: maven:3.8-openjdk-11
command: ["cat"]
tty: true
- name: postgres
image: postgres:14
env:
- name: POSTGRES_PASSWORD
value: test
'''
}
}
steps {
unstash 'backend'
container('maven') {
sh 'mvn verify -P integration'
}
}
}
}
}
stage('SonarQube') {
agent { label 'sonar' }
steps {
unstash 'backend'
withSonarQubeEnv('SonarQube') {
sh 'mvn sonar:sonar'
}
}
}
stage('Docker Build') {
agent { label 'docker' }
steps {
unstash 'backend'
unstash 'frontend'
script {
docker.withRegistry('https://registry.example.com', 'docker-registry') {
def backendImage = docker.build("${APP_NAME}-backend:${VERSION}", '-f backend/Dockerfile .')
backendImage.push()
def frontendImage = docker.build("${APP_NAME}-frontend:${VERSION}", '-f frontend/Dockerfile .')
frontendImage.push()
}
}
}
}
stage('Deploy') {
matrix {
axes {
axis {
name 'ENVIRONMENT'
values 'staging', 'production'
}
}
when {
anyOf {
branch 'main'
expression { ENVIRONMENT == 'staging' }
}
}
agent {
kubernetes {
yaml '''
apiVersion: v1
kind: Pod
spec:
containers:
- name: kubectl
image: bitnami/kubectl:latest
command: ["cat"]
tty: true
'''
}
}
stages {
stage('Deploy') {
steps {
container('kubectl') {
lock(resource: "${ENVIRONMENT}-environment") {
sh """
kubectl set image deployment/${APP_NAME} \
${APP_NAME}=registry.example.com/${APP_NAME}:${VERSION} \
-n ${ENVIRONMENT}
"""
}
}
}
}
}
}
}
}
post {
always {
node('linux') {
echo "Build completed"
}
}
}
}
下一步学习 #
小结 #
- 分布式构建提高效率和扩展性
- Master负责调度,Agent负责执行
- 使用标签进行任务调度
- 支持多种Agent类型
- 容器化Agent提供动态扩展
- 合理规划资源和环境隔离
最后更新:2026-03-28