跳转至

第八章:分布式构建

分布式构建概述

Jenkins 支持分布式构建,可以将构建任务分发到多个节点执行:

  • Master 节点:调度任务、管理配置
  • Agent 节点:执行构建任务
  • 动态 Agent:Kubernetes、Docker 动态创建

Agent 节点配置

静态 Agent 节点

在 Jenkins 管理界面添加 Agent:

  1. Manage JenkinsManage Nodes
  2. New Node → 输入节点名称
  3. 选择 Permanent Agent
  4. 配置节点参数:
  5. 远程工作目录:/home/jenkins/agent
  6. 标签:linux docker python
  7. 启动方式:SSH 或 JNLP

SSH Agent 配置

// 在 Pipeline 中使用特定 Agent
pipeline {
    agent {
        label 'linux && docker'
    }

    stages {
        stage('Build') {
            steps {
                sh 'uname -a'
            }
        }
    }
}

JNLP Agent 启动

在 Agent 机器上运行:

# 下载 agent.jar
wget http://jenkins-server/jnlpJars/agent.jar

# 启动 Agent
java -jar agent.jar -jnlpUrl http://jenkins-server/computer/agent-name/slave-agent.jnlp -secret <secret-key> -workDir "/home/jenkins/agent"

Agent 标签

// 使用标签选择 Agent
pipeline {
    agent {
        label 'docker && linux'
    }

    stages {
        stage('Build') {
            steps {
                sh 'docker --version'
            }
        }
    }
}

Docker Agent

动态 Docker Agent

pipeline {
    agent {
        docker {
            image 'node:18-alpine'
            label 'docker'
            args '-p 3000:3000'
        }
    }

    stages {
        stage('Build') {
            steps {
                sh 'node --version'
                sh 'npm install'
            }
        }
    }
}

Dockerfile Agent

pipeline {
    agent {
        dockerfile {
            filename 'Dockerfile.build'
            dir 'docker'
            label 'docker'
            additionalBuildArgs '--build-arg NODE_VERSION=18'
        }
    }

    stages {
        stage('Build') {
            steps {
                sh 'npm run build'
            }
        }
    }
}

Dockerfile 示例

# docker/Dockerfile.build
ARG NODE_VERSION=18
FROM node:${NODE_VERSION}-alpine

RUN apk add --no-cache python3 make g++

WORKDIR /app

# 预安装常用依赖
RUN npm install -g npm@latest yarn pnpm

挂载卷

pipeline {
    agent {
        docker {
            image 'maven:3.9-eclipse-temurin-17'
            args '-v $HOME/.m2:/root/.m2'
        }
    }

    stages {
        stage('Build') {
            steps {
                sh 'mvn package'
            }
        }
    }
}

Kubernetes Agent

Kubernetes Plugin 配置

在 Jenkins 中配置 Kubernetes:

  1. Manage JenkinsManage Nodes and Clouds
  2. Configure CloudsAdd a new cloudKubernetes
  3. 配置 Kubernetes 连接:
  4. Kubernetes URL:https://kubernetes.default
  5. Jenkins URL:http://jenkins:8080
  6. 命名空间:jenkins

Pod Template

pipeline {
    agent {
        kubernetes {
            yaml '''
apiVersion: v1
kind: Pod
spec:
  containers:
  - name: maven
    image: maven:3.9-eclipse-temurin-17
    command:
    - cat
    tty: true
    volumeMounts:
    - name: maven-cache
      mountPath: /root/.m2
  - name: docker
    image: docker:24-cli
    command:
    - cat
    tty: true
    volumeMounts:
    - name: docker-sock
      mountPath: /var/run/docker.sock
  volumes:
  - name: maven-cache
    persistentVolumeClaim:
      claimName: maven-cache-pvc
  - name: docker-sock
    hostPath:
      path: /var/run/docker.sock
'''
        }
    }

    stages {
        stage('Build') {
            steps {
                container('maven') {
                    sh 'mvn package'
                }
            }
        }

        stage('Docker Build') {
            steps {
                container('docker') {
                    sh 'docker build -t myapp:latest .'
                }
            }
        }
    }
}

多容器 Pod

pipeline {
    agent {
        kubernetes {
            yaml '''
apiVersion: v1
kind: Pod
spec:
  containers:
  - name: node
    image: node:18-alpine
    command:
    - cat
    tty: true
  - name: python
    image: python:3.11-slim
    command:
    - cat
    tty: true
  - name: helm
    image: alpine/helm:3.12.0
    command:
    - cat
    tty: true
'''
        }
    }

    stages {
        stage('Frontend Build') {
            steps {
                container('node') {
                    sh '''
                        npm install
                        npm run build
                    '''
                }
            }
        }

        stage('Backend Test') {
            steps {
                container('python') {
                    sh '''
                        pip install -r requirements.txt
                        pytest
                    '''
                }
            }
        }

        stage('Deploy') {
            steps {
                container('helm') {
                    sh 'helm upgrade --install myapp ./chart'
                }
            }
        }
    }
}

动态 Pod 模板

pipeline {
    agent none

    stages {
        stage('Build') {
            parallel {
                stage('Frontend') {
                    agent {
                        kubernetes {
                            yaml '''
apiVersion: v1
kind: Pod
spec:
  containers:
  - name: node
    image: node:18-alpine
    command: ['cat']
    tty: true
'''
                        }
                    }
                    steps {
                        container('node') {
                            sh 'npm run build'
                        }
                    }
                }

                stage('Backend') {
                    agent {
                        kubernetes {
                            yaml '''
apiVersion: v1
kind: Pod
spec:
  containers:
  - name: python
    image: python:3.11-slim
    command: ['cat']
    tty: true
'''
                        }
                    }
                    steps {
                        container('python') {
                            sh 'python -m pytest'
                        }
                    }
                }
            }
        }
    }
}

Agent 选择策略

按标签选择

pipeline {
    agent none

    stages {
        stage('Linux Build') {
            agent { label 'linux' }
            steps {
                sh 'make linux'
            }
        }

        stage('Windows Build') {
            agent { label 'windows' }
            steps {
                bat 'make windows'
            }
        }

        stage('macOS Build') {
            agent { label 'macos' }
            steps {
                sh 'make macos'
            }
        }
    }
}

按条件选择

pipeline {
    agent none

    stages {
        stage('Build') {
            agent {
                label "${params.PLATFORM}"
            }
            steps {
                script {
                    if (isUnix()) {
                        sh 'make build'
                    } else {
                        bat 'make build'
                    }
                }
            }
        }
    }
}

矩阵构建

pipeline {
    agent none

    matrix {
        axes {
            axis {
                name 'PLATFORM'
                values 'linux', 'windows', 'macos'
            }
            axis {
                name 'NODE_VERSION'
                values '16', '18', '20'
            }
        }

        agent {
            label "${PLATFORM}"
        }

        stages {
            stage('Build') {
                steps {
                    script {
                        if (isUnix()) {
                            sh "NODE_VERSION=${NODE_VERSION} make build"
                        } else {
                            bat "set NODE_VERSION=${NODE_VERSION} && make build"
                        }
                    }
                }
            }

            stage('Test') {
                steps {
                    script {
                        if (isUnix()) {
                            sh 'make test'
                        } else {
                            bat 'make test'
                        }
                    }
                }
            }
        }
    }
}

资源管理

资源锁

pipeline {
    agent any

    stages {
        stage('Deploy') {
            options {
                lock(resource: 'production-server', quantity: 1)
            }
            steps {
                sh 'deploy.sh'
            }
        }
    }
}

并发控制

pipeline {
    agent any

    options {
        disableConcurrentBuilds()
    }

    stages {
        stage('Build') {
            steps {
                sh 'make build'
            }
        }
    }
}

节点资源限制

pipeline {
    agent {
        label 'docker'
    }

    options {
        timeout(time: 30, unit: 'MINUTES')
    }

    stages {
        stage('Build') {
            steps {
                sh 'make build'
            }
        }
    }
}

工作区管理

自定义工作区

pipeline {
    agent {
        node {
            label 'linux'
            customWorkspace '/opt/build/my-project'
        }
    }

    stages {
        stage('Build') {
            steps {
                sh 'pwd'  // /opt/build/my-project
            }
        }
    }
}

工作区清理

pipeline {
    agent any

    options {
        skipDefaultCheckout()
    }

    stages {
        stage('Checkout') {
            steps {
                cleanWs()
                checkout scm
            }
        }

        stage('Build') {
            steps {
                sh 'make build'
            }
        }
    }

    post {
        always {
            cleanWs()
        }
    }
}

共享工作区

pipeline {
    agent any

    stages {
        stage('Setup') {
            steps {
                stash includes: 'config/**', name: 'config'
            }
        }

        stage('Build') {
            agent { label 'build-node' }
            steps {
                unstash 'config'
                sh 'make build'
            }
        }

        stage('Test') {
            agent { label 'test-node' }
            steps {
                unstash 'config'
                sh 'make test'
            }
        }
    }
}

完整示例

多平台构建

pipeline {
    agent none

    options {
        buildDiscarder(logRotator(numToKeepStr: '10'))
        timeout(time: 1, unit: 'HOURS')
    }

    environment {
        ARTIFACT_VERSION = "${env.BUILD_ID}"
    }

    stages {
        stage('Prepare') {
            agent { label 'master' }
            steps {
                script {
                    // 准备工作
                    echo "Building version ${ARTIFACT_VERSION}"
                }
            }
        }

        stage('Build') {
            parallel {
                stage('Linux') {
                    agent { label 'linux && docker' }
                    steps {
                        sh '''
                            docker build -t myapp:${ARTIFACT_VERSION}-linux .
                            docker save myapp:${ARTIFACT_VERSION}-linux -o myapp-linux.tar
                        '''
                        archiveArtifacts 'myapp-linux.tar'
                    }
                }

                stage('Windows') {
                    agent { label 'windows' }
                    steps {
                        bat '''
                            docker build -t myapp:%ARTIFACT_VERSION%-windows .
                            docker save myapp:%ARTIFACT_VERSION%-windows -o myapp-windows.tar
                        '''
                        archiveArtifacts 'myapp-windows.tar'
                    }
                }
            }
        }

        stage('Test') {
            agent {
                kubernetes {
                    yaml '''
apiVersion: v1
kind: Pod
spec:
  containers:
  - name: test
    image: python:3.11-slim
    command: ['cat']
    tty: true
'''
                }
            }
            steps {
                container('test') {
                    sh '''
                        pip install pytest
                        pytest tests/
                    '''
                }
            }
        }

        stage('Deploy') {
            agent { label 'master' }
            when {
                branch 'main'
            }
            steps {
                script {
                    // 部署到生产环境
                    sh '''
                        kubectl set image deployment/myapp myapp=myapp:${ARTIFACT_VERSION}
                    '''
                }
            }
        }
    }

    post {
        always {
            node('master') {
                cleanWs()
            }
        }

        success {
            node('master') {
                slackSend(
                    channel: '#builds',
                    color: 'good',
                    message: "✅ Multi-platform build completed: ${env.JOB_NAME} #${env.BUILD_NUMBER}"
                )
            }
        }
    }
}

小结

本章介绍了分布式构建:

  • 静态 Agent 节点配置
  • Docker 动态 Agent
  • Kubernetes Agent
  • Agent 选择策略和矩阵构建
  • 资源管理和工作区管理

下一章将通过实战项目综合应用所学知识。