06-Jenkins_分布式构建与Agent管理
·
Jenkins分布式构建与Agent管理:构建弹性扩展的CI/CD基础设施
1. 分布式架构设计原理
1.1 Master-Agent架构
Jenkins采用经典的Master-Agent分布式架构,实现构建任务的分布式执行。
1.2 通信协议架构
1.3 分布式构建优势
| 特性 | 说明 | 优势 |
|---|---|---|
| 负载分散 | 构建任务分发到多个Agent | 提高吞吐量,避免Master过载 |
| 环境隔离 | 不同Agent可配置不同环境 | 支持多平台、多版本构建 |
| 弹性扩展 | 动态Agent按需创建/销毁 | 资源按需分配,降低成本 |
| 高可用 | Agent故障不影响Master | 提高系统稳定性 |
| 安全隔离 | 敏感操作在隔离环境执行 | 降低安全风险 |
2. Agent类型与连接协议
2.1 Agent类型对比
2.2 连接协议详解
| 协议 | 连接方向 | 适用场景 | 安全性 | 穿透性 |
|---|---|---|---|---|
| SSH | Master→Agent | Agent在公网、有SSH服务 | 高(密钥认证) | 需开放SSH端口(22) |
| JNLP | Agent→Master | Agent在内网、防火墙后 | 中(密钥认证) | 仅需出站HTTP/HTTPS |
| WebSocket | Agent→Master | 网络受限环境 | 高(TLS加密) | 穿透NAT/防火墙 |
2.3 协议配置示例
/**
* 不同连接协议的Agent配置示例
*/
// ==================== SSH Agent配置 ====================
// Master主动连接Agent,适用于Agent有公网IP的情况
pipeline {
agent {
label 'ssh-agent'
}
stages {
stage('Build') {
steps {
sh 'echo "Running on SSH Agent"'
}
}
}
}
// SSH Agent在Jenkins配置中的XML表示:
/*
<hudson.plugins.sshslaves.SSHSlave>
<name>ssh-agent-01</name>
<remoteFS>/home/jenkins/agent</remoteFS>
<numExecutors>2</numExecutors>
<mode>NORMAL</mode>
<launcher class="hudson.plugins.sshslaves.SSHLauncher">
<host>192.168.1.100</host>
<port>22</port>
<credentialsId>ssh-credentials</credentialsId>
<launchTimeoutSeconds>60</launchTimeoutSeconds>
<maxNumRetries>3</maxNumRetries>
<retryWaitTime>10</retryWaitTime>
</launcher>
<label>linux docker maven</label>
</hudson.plugins.sshslaves.SSHSlave>
*/
// ==================== JNLP Agent配置 ====================
// Agent主动连接Master,适用于Agent在内网的情况
pipeline {
agent {
label 'jnlp-agent'
}
stages {
stage('Build') {
steps {
sh 'echo "Running on JNLP Agent"'
}
}
}
}
// JNLP Agent启动命令:
/*
java -jar agent.jar \
-jnlpUrl http://jenkins.example.com/computer/jnlp-agent/slave-agent.jnlp \
-secret <secret-key> \
-workDir /home/jenkins/agent
*/
// ==================== WebSocket Agent配置 ====================
// 使用WebSocket协议,适用于网络受限环境
// 在Jenkins配置中启用WebSocket:
/*
<hudson.slaves.JNLPLauncher>
<workDirSettings>
<disabled>false</disabled>
<internalDir>remoting</internalDir>
</workDirSettings>
<webSocket>true</webSocket>
</hudson.slaves.JNLPLauncher>
*/
// WebSocket Agent启动命令:
/*
java -jar agent.jar \
-webSocket \
-url http://jenkins.example.com \
-secret <secret-key> \
-name websocker-agent \
-workDir /home/jenkins/agent
*/
3. 静态Agent配置管理
3.1 SSH Agent完整配置
<!--
文件: JENKINS_HOME/config.xml (SSH Agent配置部分)
描述: SSH Agent完整配置示例
-->
<hudson.plugins.sshslaves.SSHSlave>
<!-- 基本信息 -->
<name>linux-build-agent-01</name>
<description>Linux构建节点 - Docker环境</description>
<remoteFS>/home/jenkins/agent</remoteFS>
<numExecutors>4</numExecutors>
<mode>NORMAL</mode>
<!-- 启动器配置 -->
<launcher class="hudson.plugins.sshslaves.SSHLauncher">
<host>192.168.1.100</host>
<port>22</port>
<credentialsId>ssh-agent-credentials</credentialsId>
<!-- 启动超时配置 -->
<launchTimeoutSeconds>120</launchTimeoutSeconds>
<maxNumRetries>5</maxNumRetries>
<retryWaitTime>15</retryWaitTime>
<!-- SSH主机密钥验证策略 -->
<sshHostKeyVerificationStrategy class="hudson.plugins.sshslaves.verifiers.KnownHostsFileKeyVerificationStrategy"/>
<!-- TCP保活 -->
<tcpKeepAlive>true</tcpKeepAlive>
<!-- 启动前检查 -->
<sshLauncherBuilder class="hudson.plugins.sshslaves.SSHLauncher$Builder">
<javaPath>/usr/lib/jvm/java-11-openjdk/bin/java</javaPath>
<jvmOptions>-Xmx2g -XX:+UseG1GC</jvmOptions>
<prefixStartSlaveCmd></prefixStartSlaveCmd>
<suffixStartSlaveCmd></suffixStartSlaveCmd>
</sshLauncherBuilder>
<!-- Agent启动命令 -->
<agentUser>jenkins</agentUser>
<agentJVMOptions>-Xmx4g -XX:+UseG1GC</agentJVMOptions>
</launcher>
<!-- 保留策略 -->
<retentionStrategy class="hudson.slaves.RetentionStrategy$Always"/>
<!-- 标签 -->
<label>linux docker maven gradle node18 python3</label>
<!-- 节点属性 -->
<nodeProperties>
<!-- 环境变量 -->
<hudson.slaves.EnvironmentVariablesNodeProperty>
<envVars serialization="custom">
<tree-map>
<entry>
<string>JAVA_HOME</string>
<string>/usr/lib/jvm/java-11-openjdk</string>
</entry>
<entry>
<string>MAVEN_HOME</string>
<string>/usr/share/maven</string>
</entry>
<entry>
<string>DOCKER_HOST</string>
<string>unix:///var/run/docker.sock</string>
</entry>
</tree-map>
</envVars>
</hudson.slaves.EnvironmentVariablesNodeProperty>
<!-- 工具位置 -->
<hudson.tools.ToolLocationNodeProperty>
<locations>
<hudson.tools.ToolLocation>
<key>hudson.model.JDK$DescriptorImpl@JDK-11</key>
<home>/usr/lib/jvm/java-11-openjdk</home>
</hudson.tools.ToolLocation>
<hudson.tools.ToolLocation>
<key>hudson.tasks.Maven$MavenInstallation$DescriptorImpl@Maven-3.8</key>
<home>/usr/share/maven</home>
</hudson.tools.ToolLocation>
</locations>
</hudson.tools.ToolLocationNodeProperty>
</nodeProperties>
</hudson.plugins.sshslaves.SSHSlave>
3.2 JNLP Agent配置
/**
* JNLP Agent配置与管理
*/
// ==================== Jenkins中配置JNLP Agent ====================
// 使用JCasC配置
jenkins:
nodes:
- permanent:
name: "jnlp-agent-01"
remoteFS: "/home/jenkins/agent"
numExecutors: 2
mode: NORMAL
retentionStrategy:
onDemand:
idleMinutes: 30
launcher:
jnlp:
workDirSettings:
disabled: false
internalDir: "remoting"
failIfWorkDirIsMissing: false
labelString: "linux maven gradle"
nodeProperties:
- envVars:
env:
- key: "JAVA_HOME"
value: "/usr/lib/jvm/java-11-openjdk"
// ==================== JNLP Agent启动脚本 ====================
#!/bin/bash
# JNLP Agent启动脚本
# 文件: start-agent.sh
JENKINS_URL="http://jenkins.example.com"
AGENT_NAME="jnlp-agent-01"
SECRET_KEY="your-secret-key"
WORK_DIR="/home/jenkins/agent"
JVM_OPTS="-Xmx2g -XX:+UseG1GC"
# 下载agent.jar
curl -sSL ${JENKINS_URL}/jnlpJars/agent.jar -o agent.jar
# 启动Agent
java ${JVM_OPTS} -jar agent.jar \
-jnlpUrl ${JENKINS_URL}/computer/${AGENT_NAME}/slave-agent.jnlp \
-secret ${SECRET_KEY} \
-workDir ${WORK_DIR} \
-noReconnectAfter 10m
// ==================== JNLP Agent作为系统服务 ====================
# 文件: /etc/systemd/system/jenkins-agent.service
[Unit]
Description=Jenkins JNLP Agent
After=network.target
[Service]
Type=simple
User=jenkins
Group=jenkins
WorkingDirectory=/home/jenkins/agent
ExecStart=/usr/bin/java -Xmx2g -jar /home/jenkins/agent/agent.jar \
-jnlpUrl http://jenkins.example.com/computer/jnlp-agent-01/slave-agent.jnlp \
-secret YOUR_SECRET_KEY \
-workDir /home/jenkins/agent
Restart=always
RestartSec=10
[Install]
WantedBy=multi-user.target
3.3 Agent配置最佳实践
/**
* Agent配置最佳实践示例
*/
// ==================== 1. 资源限制配置 ====================
pipeline {
agent {
label 'linux'
// 自定义工作空间
customWorkspace "/opt/jenkins/workspaces/${JOB_NAME}/${BUILD_NUMBER}"
}
options {
// 超时控制
timeout(time: 60, unit: 'MINUTES')
// 禁止并发构建(保护资源)
disableConcurrentBuilds()
}
stages {
stage('Build') {
steps {
sh 'mvn clean package'
}
}
}
}
// ==================== 2. 按需保留策略 ====================
// Agent在空闲一段时间后自动断开
/*
<retentionStrategy class="hudson.slaves.RetentionStrategy$OnDemand">
<idleMinutes>30</idleMinutes>
</retentionStrategy>
*/
// ==================== 3. 一次性格式策略 ====================
// 每次构建后清理工作空间
/*
<retentionStrategy class="hudson.slaves.RetentionStrategy$Once">
<maxUses>10</maxUses>
</retentionStrategy>
*/
// ==================== 4. Docker Agent一次性运行 ====================
pipeline {
agent {
docker {
image 'maven:3.8-openjdk-11'
args '--rm -v /tmp/.m2:/root/.m2'
reuseNode true
}
}
stages {
stage('Build') {
steps {
sh 'mvn clean package'
}
}
}
}
4. Kubernetes动态Agent
4.1 Kubernetes Agent架构
4.2 Kubernetes Plugin配置
# 文件: Jenkins配置即代码 (JCasC)
# Kubernetes云配置
jenkins:
clouds:
- kubernetes:
name: "kubernetes"
serverUrl: "https://kubernetes.default"
namespace: "jenkins"
jenkinsUrl: "http://jenkins.jenkins.svc.cluster.local:8080"
jenkinsTunnel: "jenkins.jenkins.svc.cluster.local:50000"
# 连接超时
connectTimeout: 5
readTimeout: 15
# 最大并发Pod数
containerCap: 50
# 保留时间
retentionTimeout: 5
# Pod模板
templates:
# 默认Pod模板
- name: "default"
namespace: "jenkins"
label: "kubernetes default"
# ServiceAccount
serviceAccount: "jenkins-agent"
# 资源限制
nodeSelector:
"kubernetes.io/os": "linux"
# 容器配置
containers:
- name: "jnlp"
image: "jenkins/inbound-agent:4.11.2"
args: "^${computer.jnlpmac} ^${computer.name}"
envVars:
- envVar:
key: "JENKINS_URL"
value: "http://jenkins.jenkins.svc.cluster.local:8080"
resourceLimitCpu: "500m"
resourceLimitMemory: "1Gi"
resourceRequestCpu: "200m"
resourceRequestMemory: "512Mi"
# 工作空间卷
workspaceVolume:
emptyDirWorkspaceVolume:
memory: false
# 卷挂载
volumes:
- hostPathVolume:
mountPath: "/var/run/docker.sock"
hostPath: "/var/run/docker.sock"
- persistentVolumeClaim:
mountPath: "/root/.m2/repository"
claimName: "maven-cache-pvc"
readOnly: false
# Maven构建模板
- name: "maven"
namespace: "jenkins"
label: "maven kubernetes"
serviceAccount: "jenkins-agent"
containers:
- name: "jnlp"
image: "jenkins/inbound-agent:4.11.2"
resourceLimitCpu: "500m"
resourceLimitMemory: "1Gi"
- name: "maven"
image: "maven:3.8.6-openjdk-11"
command: "sleep"
args: "99d"
resourceLimitCpu: "2"
resourceLimitMemory: "4Gi"
resourceRequestCpu: "1"
resourceRequestMemory: "2Gi"
envVars:
- envVar:
key: "MAVEN_OPTS"
value: "-Xmx3g -XX:+UseG1GC"
ttyEnabled: true
volumes:
- persistentVolumeClaim:
mountPath: "/root/.m2/repository"
claimName: "maven-cache-pvc"
# Docker构建模板
- name: "docker"
namespace: "jenkins"
label: "docker kubernetes"
serviceAccount: "jenkins-agent"
containers:
- name: "jnlp"
image: "jenkins/inbound-agent:4.11.2"
- name: "docker"
image: "docker:20.10.18"
command: "sleep"
args: "99d"
ttyEnabled: true
envVars:
- envVar:
key: "DOCKER_HOST"
value: "tcp://docker-dind:2376"
- envVar:
key: "DOCKER_TLS_VERIFY"
value: "1"
- envVar:
key: "DOCKER_CERT_PATH"
value: "/certs/client"
volumes:
- hostPathVolume:
mountPath: "/var/run/docker.sock"
hostPath: "/var/run/docker.sock"
4.3 Pipeline中使用Kubernetes Agent
/**
* Kubernetes动态Agent完整示例
*/
// ==================== 方式1: 使用预定义模板 ====================
pipeline {
agent {
kubernetes {
label 'maven-build-${BUILD_NUMBER}'
cloud 'kubernetes'
inheritFrom 'maven' // 继承预定义模板
}
}
stages {
stage('Build') {
steps {
container('maven') {
sh 'mvn clean package'
}
}
}
}
}
// ==================== 方式2: 内联Pod定义 ====================
pipeline {
agent {
kubernetes {
cloud 'kubernetes'
label 'custom-build-${BUILD_NUMBER}'
yaml '''
apiVersion: v1
kind: Pod
metadata:
labels:
app: jenkins-agent
build: ${BUILD_NUMBER}
spec:
serviceAccountName: jenkins-agent
securityContext:
runAsUser: 1000
fsGroup: 1000
containers:
- name: jnlp
image: jenkins/inbound-agent:4.11.2
args: ['$(JENKINS_SECRET)', '$(JENKINS_NAME)']
resources:
requests:
cpu: "200m"
memory: "512Mi"
limits:
cpu: "500m"
memory: "1Gi"
- name: maven
image: maven:3.8.6-openjdk-11
command: ['sleep', '99d']
resources:
requests:
cpu: "1"
memory: "2Gi"
limits:
cpu: "2"
memory: "4Gi"
volumeMounts:
- name: maven-cache
mountPath: /root/.m2/repository
- name: docker
image: docker:20.10.18
command: ['sleep', '99d']
resources:
requests:
cpu: "500m"
memory: "1Gi"
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 with Maven') {
steps {
container('maven') {
sh '''
mvn clean package -DskipTests
mvn test
'''
}
}
post {
always {
junit '**/target/surefire-reports/*.xml'
}
}
}
stage('Docker Build') {
steps {
container('docker') {
sh '''
docker build -t myapp:${BUILD_NUMBER} .
docker push registry.example.com/myapp:${BUILD_NUMBER}
'''
}
}
}
}
}
// ==================== 方式3: 动态生成Pod定义 ====================
pipeline {
agent none
parameters {
choice(name: 'JAVA_VERSION', choices: ['11', '17'], description: 'Java版本')
choice(name: 'BUILD_TOOL', choices: ['maven', 'gradle'], description: '构建工具')
}
stages {
stage('Dynamic Agent Build') {
agent {
kubernetes {
cloud 'kubernetes'
label 'dynamic-${BUILD_NUMBER}'
yamlTemplate """
apiVersion: v1
kind: Pod
spec:
containers:
- name: jnlp
image: jenkins/inbound-agent:4.11.2
- name: build
image: ${params.BUILD_TOOL}:latest-openjdk-${params.JAVA_VERSION}
command: ['sleep', '99d']
"""
defaultContainer 'build'
}
}
steps {
script {
if (params.BUILD_TOOL == 'maven') {
sh 'mvn clean package'
} else {
sh './gradlew build'
}
}
}
}
}
}
// ==================== 方式4: 多容器协作 ====================
pipeline {
agent {
kubernetes {
cloud 'kubernetes'
yaml '''
apiVersion: v1
kind: Pod
spec:
containers:
- name: jnlp
image: jenkins/inbound-agent:4.11.2
- name: maven
image: maven:3.8.6-openjdk-11
command: ['sleep', '99d']
ttyEnabled: true
- name: node
image: node:18
command: ['sleep', '99d']
ttyEnabled: true
- name: python
image: python:3.11
command: ['sleep', '99d']
ttyEnabled: true
'''
}
}
stages {
stage('Build Backend') {
steps {
container('maven') {
dir('backend') {
sh 'mvn clean package'
}
}
}
}
stage('Build Frontend') {
steps {
container('node') {
dir('frontend') {
sh 'npm ci && npm run build'
}
}
}
}
stage('Run Python Tests') {
steps {
container('python') {
dir('scripts') {
sh 'pip install -r requirements.txt && pytest'
}
}
}
}
}
}
5. Docker动态Agent
5.1 Docker Agent架构
5.2 Docker Agent配置
/**
* Docker动态Agent配置示例
*/
// ==================== 方式1: 简单Docker Agent ====================
pipeline {
agent {
docker {
image 'maven:3.8-openjdk-11'
args '-v /tmp/.m2:/root/.m2'
}
}
stages {
stage('Build') {
steps {
sh 'mvn clean package'
}
}
}
}
// ==================== 方式2: 带凭证的Docker Agent ====================
pipeline {
agent {
docker {
image 'maven:3.8-openjdk-11'
args '-v /tmp/.m2:/root/.m2 -v /tmp/.gradle:/root/.gradle'
registryUrl 'https://registry.example.com'
registryCredentialsId 'docker-registry-credentials'
}
}
stages {
stage('Build') {
steps {
sh 'mvn clean package'
}
}
}
}
// ==================== 方式3: 自定义Dockerfile ====================
pipeline {
agent {
dockerfile {
filename 'Dockerfile.build'
dir 'docker'
additionalBuildArgs '--build-arg JAVA_VERSION=11'
args '-v /tmp/.m2:/root/.m2'
}
}
stages {
stage('Build') {
steps {
sh 'mvn clean package'
}
}
}
}
// ==================== 方式4: Docker模板标签 ====================
pipeline {
agent none
stages {
stage('Build on Multiple Platforms') {
parallel {
stage('Linux') {
agent {
docker {
image 'maven:3.8-openjdk-11'
label 'docker-linux'
}
}
steps {
sh 'mvn clean package'
}
}
stage('Windows') {
agent {
docker {
image 'maven:3.8-openjdk-11-windowsservercore'
label 'docker-windows'
}
}
steps {
bat 'mvn clean package'
}
}
}
}
}
}
// ==================== 方式5: 动态Docker Agent ====================
pipeline {
agent none
parameters {
string(name: 'DOCKER_IMAGE', defaultValue: 'maven:3.8-openjdk-11',
description: 'Docker镜像')
}
stages {
stage('Dynamic Docker Build') {
agent {
docker {
image "${params.DOCKER_IMAGE}"
args '-v /tmp/.m2:/root/.m2'
}
}
steps {
sh 'mvn clean package'
}
}
}
}
5.3 Docker Compose多容器
/**
* 使用Docker Compose运行多容器Agent
*/
// ==================== docker-compose.yml ====================
version: '3.8'
services:
maven:
image: maven:3.8-openjdk-11
command: sleep infinity
volumes:
- maven-cache:/root/.m2/repository
- workspace:/workspace
working_dir: /workspace
node:
image: node:18
command: sleep infinity
volumes:
- npm-cache:/root/.npm
- workspace:/workspace
working_dir: /workspace
selenium:
image: selenium/standalone-chrome:latest
ports:
- "4444:4444"
volumes:
- workspace:/workspace
volumes:
maven-cache:
npm-cache:
workspace:
// ==================== Pipeline使用Docker Compose ====================
pipeline {
agent {
label 'docker'
}
stages {
stage('Start Services') {
steps {
sh 'docker-compose up -d'
}
}
stage('Build Backend') {
steps {
sh '''
docker-compose exec -T maven mvn clean package
'''
}
}
stage('Build Frontend') {
steps {
sh '''
docker-compose exec -T node npm ci
docker-compose exec -T node npm run build
'''
}
}
stage('E2E Tests') {
steps {
sh '''
docker-compose exec -T node npm run e2e
'''
}
}
}
post {
always {
sh 'docker-compose down -v'
}
}
}
6. 负载均衡与调度策略
6.1 调度策略架构
6.2 调度策略配置
/**
* 负载均衡与调度策略配置
*/
// ==================== 1. Label约束调度 ====================
pipeline {
// 使用Label约束选择Agent
agent { label 'linux && docker && maven' }
stages {
stage('Build') {
steps {
sh 'mvn clean package'
}
}
}
}
// ==================== 2. 排他性Agent ====================
// Agent配置为EXCLUSIVE模式,仅执行指定Job
/*
<mode>EXCLUSIVE</mode>
*/
// ==================== 3. 自定义负载均衡 ====================
// 使用Groovy脚本实现自定义调度
import hudson.model.*
import jenkins.model.*
def selectLeastLoadedAgent(Label label) {
def computers = Jenkins.instance.getComputers()
// 过滤匹配Label的Agent
def matchingComputers = computers.findAll { computer ->
label == null || computer.node?.assignedLabel?.matches(label)
}
// 选择负载最低的Agent
return matchingComputers.min { a, b ->
a.countBusy() <=> b.countBusy()
}
}
// ==================== 4. 优先级调度 ====================
// 安装Priority Sorter插件配置优先级
// 在Pipeline中使用优先级
pipeline {
agent any
options {
// 设置构建优先级
buildDiscarder(logRotator(numToKeepStr: '10'))
}
stages {
stage('High Priority Build') {
steps {
echo 'This is a high priority build'
}
}
}
}
// ==================== 5. 亲和性调度 ====================
// 让相关任务在同一Agent上执行
pipeline {
agent {
label 'linux'
}
stages {
stage('Prepare') {
steps {
script {
// 记录当前Agent
env.PREFERRED_AGENT = env.NODE_NAME
}
}
}
stage('Build') {
agent {
label env.PREFERRED_AGENT
}
steps {
sh 'mvn clean package'
}
}
stage('Test') {
agent {
label env.PREFERRED_AGENT
}
steps {
sh 'mvn test'
}
}
}
}
6.3 队列管理策略
/**
* 队列管理策略配置
*/
// ==================== 1. 并发限制 ====================
pipeline {
agent any
options {
// 禁止并发构建
disableConcurrentBuilds()
// 或允许并发但限制数量
// disableConcurrentBuilds(abortPrevious: false)
}
stages {
stage('Build') {
steps {
sh 'sleep 60'
}
}
}
}
// ==================== 2. 资源锁 ====================
pipeline {
agent any
stages {
stage('Exclusive Resource') {
steps {
// 使用lock步骤确保资源独占
lock(resource: 'shared-database', quantity: 1) {
sh 'run-tests.sh'
}
}
}
stage('Multiple Resources') {
steps {
lock(resources: ['server-a', 'server-b'], variable: 'LOCKED_SERVERS') {
echo "Locked servers: ${env.LOCKED_SERVERS}"
}
}
}
}
}
// ==================== 3. 节流分类 ====================
// 在Jenkins配置中设置Throttle Categories
/*
<throttle-concurrent-builds>
<categories>
<category>
<name>heavy-builds</name>
<maxConcurrentPerNode>1</maxConcurrentPerNode>
<maxConcurrentTotal>3</maxConcurrentTotal>
</category>
</categories>
</throttle-concurrent-builds>
*/
// Pipeline中使用节流
pipeline {
agent any
options {
throttleJobProperty(
categories: ['heavy-builds'],
throttleEnabled: true,
throttleOption: 'category'
)
}
stages {
stage('Heavy Build') {
steps {
sh './heavy-build.sh'
}
}
}
}
7. Agent监控与运维
7.1 监控指标
7.2 监控配置
/**
* Agent监控配置示例
*/
// ==================== 1. 健康检查脚本 ====================
// 在Jenkins Script Console中运行
import hudson.model.*
import jenkins.model.*
import hudson.slaves.*
Jenkins jenkins = Jenkins.getInstance()
println "=== Agent Status Report ==="
println ""
jenkins.computers.each { computer ->
println "Agent: ${computer.name}"
println " Status: ${computer.offline ? 'OFFLINE' : 'ONLINE'}"
println " Executors: ${computer.numExecutors}"
println " Busy: ${computer.countBusy()}"
println " Idle: ${computer.countIdle()}"
if (computer.offline) {
println " Offline Cause: ${computer.offlineCause}"
}
// 获取系统信息(如果Agent在线)
if (!computer.offline) {
try {
def mem = computer.node?.toComputer()?.getSystemInfo()?.getMemory()
if (mem) {
println " Memory: ${mem}"
}
} catch (Exception e) {
println " Memory: Unable to retrieve"
}
}
println ""
}
// ==================== 2. Prometheus监控集成 ====================
// 安装Prometheus插件后配置
// prometheus.yml
/*
scrape_configs:
- job_name: 'jenkins'
metrics_path: '/prometheus'
static_configs:
- targets: ['jenkins.example.com:8080']
*/
// 关键监控指标:
// - jenkins_nodes_online: 在线节点数
// - jenkins_nodes_offline: 离线节点数
// - jenkins_executors_available: 可用Executor数
// - jenkins_executors_busy: 繁忙Executor数
// - jenkins_queue_size: 队列大小
// - jenkins_queue_blocked: 阻塞任务数
// ==================== 3. 自动恢复脚本 ====================
// 定期检查并尝试恢复离线Agent
import hudson.model.*
import jenkins.model.*
import hudson.slaves.*
Jenkins jenkins = Jenkins.getInstance()
jenkins.computers.each { computer ->
if (computer.offline && computer.offlineCause != null) {
println "Attempting to reconnect: ${computer.name}"
try {
// 尝试重新连接
computer.connect(false)
// 等待连接
Thread.sleep(30000)
if (computer.offline) {
println " Still offline after reconnect attempt"
// 发送告警通知
// sendAlert(computer.name, computer.offlineCause)
} else {
println " Successfully reconnected"
}
} catch (Exception e) {
println " Reconnect failed: ${e.message}"
}
}
}
// ==================== 4. 资源使用监控 ====================
pipeline {
agent any
stages {
stage('Monitor Resources') {
steps {
script {
// 获取当前节点资源信息
def nodeInfo = sh(
script: '''
echo "CPU: $(top -bn1 | grep 'Cpu(s)' | awk '{print $2}')%"
echo "Memory: $(free -m | awk '/Mem/{printf "%.1f%%", $3/$2*100}')"
echo "Disk: $(df -h / | awk 'NR==2{print $5}')"
''',
returnStdout: true
)
echo "Node Resources:\n${nodeInfo}"
// 记录到构建描述
currentBuild.description = nodeInfo
}
}
}
}
}
7.3 运维最佳实践
/**
* Agent运维最佳实践
*/
// ==================== 1. 定期清理工作空间 ====================
pipeline {
agent any
options {
// 构建后清理
skipDefaultCheckout(true)
}
stages {
stage('Checkout') {
steps {
// 清理并检出
cleanWs()
checkout scm
}
}
stage('Build') {
steps {
sh 'mvn clean package'
}
}
}
post {
cleanup {
// 清理临时文件
cleanWs(
cleanWhenSuccess: true,
cleanWhenFailure: false,
deleteDirs: true,
patterns: [
[pattern: '**/target/**', type: 'INCLUDE']
]
)
}
}
}
// ==================== 2. Agent自动扩缩容 ====================
// 使用Kubernetes实现自动扩缩容
// Kubernetes Horizontal Pod Autoscaler配置
/*
apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
name: jenkins-agent-hpa
spec:
scaleTargetRef:
apiVersion: apps/v1
kind: Deployment
name: jenkins-agent
minReplicas: 2
maxReplicas: 20
metrics:
- type: Resource
resource:
name: cpu
target:
type: Utilization
averageUtilization: 70
- type: Resource
resource:
name: memory
target:
type: Utilization
averageUtilization: 80
*/
// ==================== 3. Agent配置版本控制 ====================
// 使用JCasC管理Agent配置
// jenkins.yaml
jenkins:
nodes:
- permanent:
name: "agent-01"
remoteFS: "/home/jenkins/agent"
numExecutors: 2
mode: NORMAL
launcher:
ssh:
host: "192.168.1.100"
port: 22
credentialsId: "ssh-credentials"
labelString: "linux docker"
nodeProperties:
- envVars:
env:
- key: "JAVA_HOME"
value: "/usr/lib/jvm/java-11"
// ==================== 4. 故障自动转移 ====================
pipeline {
agent none
stages {
stage('Build with Failover') {
steps {
script {
def agents = ['agent-01', 'agent-02', 'agent-03']
def success = false
for (agent in agents) {
try {
node(agent) {
sh 'mvn clean package'
success = true
break
}
} catch (Exception e) {
echo "Build failed on ${agent}: ${e.message}"
}
}
if (!success) {
error("All agents failed")
}
}
}
}
}
}
总结
本文深入讲解了Jenkins分布式构建与Agent管理,涵盖以下关键知识点:
| 主题 | 核心要点 |
|---|---|
| 分布式架构 | Master-Agent模式、通信协议、架构优势 |
| Agent类型 | 静态Agent、动态Agent、连接协议对比 |
| 静态Agent | SSH配置、JNLP配置、最佳实践 |
| Kubernetes Agent | 云配置、Pod模板、Pipeline集成 |
| Docker Agent | 镜像配置、Dockerfile、多容器编排 |
| 负载均衡 | Label调度、优先级、资源锁、节流策略 |
| 监控运维 | 监控指标、健康检查、自动恢复、最佳实践 |
更多推荐



所有评论(0)