Jenkins入门教程(十二):Jenkins分布式构建与Agent节点

当构建任务增多时,单台Jenkins服务器可能不够用。本文将详细介绍Jenkins的分布式构建架构,包括Agent配置和实际操作示例。

Master-Agent架构

Jenkins采用Master-Agent架构:

  • Master节点:负责调度任务、存储配置、展示界面
  • Agent节点:负责实际执行构建任务

这种架构支持水平扩展构建能力,可以同时运行多个构建任务。

添加SSH Agent节点

步骤1:准备Agent服务器

# 在Agent服务器上执行
# 安装Java(Jenkins Agent需要Java)
sudo apt update
sudo apt install openjdk-17-jdk -y

# 验证Java安装
java -version

# 创建Jenkins工作目录
sudo mkdir -p /var/lib/jenkins
sudo useradd -d /var/lib/jenkins jenkins
sudo chown jenkins:jenkins /var/lib/jenkins

步骤2:配置SSH密钥

# 在Jenkins Master上生成SSH密钥(如果没有)
sudo -u jenkins ssh-keygen -t rsa -b 4096 -f /var/lib/jenkins/.ssh/id_rsa -N ''

# 复制公钥到Agent服务器
sudo -u jenkins ssh-copy-id jenkins@agent-server-ip

# 测试SSH连接
sudo -u jenkins ssh jenkins@agent-server-ip 'echo "Connection successful"'

步骤3:在Jenkins中添加节点

  • 进入系统管理 > 节点管理 > 新建节点
  • 输入节点名称,选择"固定代理"
  • 配置以下参数:
名称: linux-agent-01
执行器数量: 4
远程工作目录: /var/lib/jenkins
标签: linux docker java
用法: 尽可能多地使用这个节点
启动方式: Launch agents via SSH
主机: 192.168.1.100
凭据: jenkins-ssh-key
Host Key Verification Strategy: Non verifying

添加JNLP Agent节点

JNLP方式由Agent主动连接Master,适合Agent在防火墙后面的情况:

步骤1:在Jenkins中创建节点

  • 新建节点,启动方式选择"Launch agent by connecting it to the controller"
  • 保存后,记录显示的secret和agent.jar下载链接

步骤2:在Agent服务器上启动

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

# 启动Agent(替换实际的secret)
java -jar agent.jar \
    -jnlpUrl http://jenkins-master:8080/computer/agent-01/jenkins-agent.jnlp \
    -secret abc123def456... \
    -workDir "/var/lib/jenkins"

执行结果:

$ java -jar agent.jar -jnlpUrl ...
Feb 08, 2026 12:00:00 PM hudson.remoting.jnlp.Main createEngine
INFO: Setting up agent: agent-01
Feb 08, 2026 12:00:01 PM hudson.remoting.jnlp.Main$CuiListener status
INFO: Locating server among [http://jenkins-master:8080/]
Feb 08, 2026 12:00:02 PM hudson.remoting.jnlp.Main$CuiListener status
INFO: Agent discovery successful
Feb 08, 2026 12:00:02 PM hudson.remoting.jnlp.Main$CuiListener status
INFO: Connected

使用标签分配任务

为节点设置标签,在Pipeline中指定标签:

pipeline {
    agent {
        label 'linux && docker'  // 需要同时有linux和docker标签
    }
    
    stages {
        stage('Check Node') {
            steps {
                sh '''
                    echo "Running on node: ${NODE_NAME}"
                    echo "Node labels: ${NODE_LABELS}"
                    echo "Workspace: ${WORKSPACE}"
                '''
            }
        }
        
        stage('Docker Build') {
            steps {
                sh 'docker version'
            }
        }
    }
}

执行结果:

[Pipeline] node
Running on linux-agent-01 in /var/lib/jenkins/workspace/my-job
[Pipeline] sh
+ echo 'Running on node: linux-agent-01'
Running on node: linux-agent-01
+ echo 'Node labels: linux docker java'
Node labels: linux docker java

不同阶段使用不同节点

pipeline {
    agent none  // 不指定全局agent
    
    stages {
        stage('Build on Linux') {
            agent { label 'linux' }
            steps {
                sh 'echo "Building on Linux: ${NODE_NAME}"'
                sh 'make build'
                stash includes: 'dist/**', name: 'linux-build'
            }
        }
        
        stage('Build on Windows') {
            agent { label 'windows' }
            steps {
                bat 'echo Building on Windows: %NODE_NAME%'
                bat 'msbuild solution.sln'
            }
        }
        
        stage('Deploy') {
            agent { label 'deploy' }
            steps {
                unstash 'linux-build'
                sh './deploy.sh'
            }
        }
    }
}

Kubernetes动态Agent

使用Kubernetes插件动态创建Pod作为Agent:

pipeline {
    agent {
        kubernetes {
            yaml '''
apiVersion: v1
kind: Pod
spec:
  containers:
  - name: maven
    image: maven:3.8-openjdk-17
    command:
    - sleep
    args:
    - infinity
    resources:
      limits:
        memory: "2Gi"
        cpu: "1"
  - name: docker
    image: docker:24-dind
    securityContext:
      privileged: true
'''
        }
    }
    
    stages {
        stage('Build') {
            steps {
                container('maven') {
                    sh 'mvn clean package'
                }
            }
        }
        
        stage('Docker Build') {
            steps {
                container('docker') {
                    sh 'docker build -t myapp:latest .'
                }
            }
        }
    }
}

监控Agent状态

在节点管理页面可以查看各Agent的状态:

# 使用Jenkins CLI查看节点状态
java -jar jenkins-cli.jar -s http://localhost:8080/ -auth admin:token list-agents

# 输出示例
linux-agent-01 (online)
linux-agent-02 (online)
windows-agent-01 (offline)

Agent作为systemd服务

# /etc/systemd/system/jenkins-agent.service
[Unit]
Description=Jenkins Agent
After=network.target

[Service]
User=jenkins
WorkingDirectory=/var/lib/jenkins
ExecStart=/usr/bin/java -jar /var/lib/jenkins/agent.jar -jnlpUrl http://jenkins-master:8080/computer/agent-01/jenkins-agent.jnlp -secret SECRET_KEY -workDir /var/lib/jenkins
Restart=always
RestartSec=10

[Install]
WantedBy=multi-user.target
# 启用服务
sudo systemctl daemon-reload
sudo systemctl enable jenkins-agent
sudo systemctl start jenkins-agent
sudo systemctl status jenkins-agent

总结

本文详细介绍了Jenkins的分布式构建架构,包括SSH Agent、JNLP Agent、Kubernetes动态Agent的配置方法。分布式构建可以显著提高构建效率。

下一篇我们将学习Jenkins的邮件和通知配置。

发表回复

后才能评论