ARTICLE DETAIL

资讯详情

深耕网站视觉设计与运营推广的一线实战洞察。

【CI/CD·Jenkins篇】多节点构建:Agent 配置与任务分发策略

【CI/CD·Jenkins篇】多节点构建:Agent 配置与任务分发策略 前言当团队规模扩大到几十个微服务、几十条流水线时单个 Jenkins Agent 就成了瓶颈——构建排队、资源争抢、环境冲突。本篇讲清楚如何规划多节点构建集群让构建任务高效分发到合适的 Agent 上。一、为什么需要多节点单节点的瓶颈单节点场景 10个流水线同时触发 → 排队 → 第1个跑完(15分钟) → 第2个开始... → 最后一个等了150分钟才开始 多节点场景 10个流水线 → 分散到5个Agent → 每个节点跑2个 → 30分钟全部完成多节点规划原则| 原则 | 说明 ||------|------|| 按技术栈分组 | Java 节点、Go 节点、前端节点分离 || 按任务类型分组 | 构建节点、部署节点、测试节点分离 || 按环境隔离 | 生产部署节点与构建节点网络隔离 || 按负载弹性 | 基础节点常驻 弹性节点按需扩缩 |二、Agent 标签策略标签设计规范命名规则: 技术栈-任务类型-序号 示例标签: java-build-01 # Java 构建 java-build-02 go-build-01 # Go 构建 frontend-build-01 # 前端构建 docker-build-01 # Docker 镜像构建 k8s-deploy-01 # K8s 部署有 kubectl k8s-deploy-02 e2e-test-01 # E2E 测试有浏览器Jenkins 中配置 Agent 标签在 Manage Jenkins → Nodes → 节点配置中设置 Labelsagent-java-build-01: Labels: java-build,maven,gradle # 多个标签用逗号分隔Pipeline 中可以用任意一个匹配 agent-docker-build-01: Labels: docker-build,docker # 这个节点有 Docker daemon agent-k8s-deploy-01: Labels: k8s-deploy,kubectl # 这个节点有 kubectl 和集群 kubeconfigPipeline 中使用标签pipeline { // 精确匹配必须有 java-build 标签 agent { label java-build } stages { stage(Build) { steps { sh mvn clean package } } stage(Docker Build) { // 切换到有 docker 标签的节点 agent { label docker-build } steps { sh docker build -t myapp:${BUILD_NUMBER} . sh docker push registry.com/myapp:${BUILD_NUMBER} } } stage(Deploy) { // 切换到有 k8s-deploy 标签的节点 agent { label k8s-deploy } steps { sh kubectl set image deployment/myapp appregistry.com/myapp:${BUILD_NUMBER} -n prod sh kubectl rollout status deployment/myapp -n prod } } } }**踩坑提示**stage 级别的 agent 指令会导致工作空间切换。每个 stage 切换节点后工作空间是新的之前构建的产物不会自动带过去。需要用 stash/unstash 或共享存储来传递产物。使用 stash 传递产物pipeline { agent { label java-build } stages { stage(Build) { steps { sh mvn clean package -DskipTests // 打包产物 stash includes: target/*.jar, name: app-jar } } stage(Docker Build) { agent { label docker-build } steps { // 取回产物 unstash app-jar sh docker build -t myapp:${BUILD_NUMBER} . sh docker push registry.com/myapp:${BUILD_NUMBER} } } stage(Deploy) { agent { label k8s-deploy } steps { sh kubectl set image deployment/myapp appregistry.com/myapp:${BUILD_NUMBER} -n prod } } } }三、Kubernetes 动态 Agent为什么用动态 Agent静态 Agent 的问题固定 5 个 Agent → 平时利用率 20% → 浪费资源 上线日不够用 → 构建排队动态 Agent 的优势Pod 按需创建 → 高峰期自动扩容到 20 个 空闲期自动缩到 0 每次构建都是全新环境 → 无环境污染安装 K8s 插件并配置Manage Jenkins → System → Cloud → Kubernetes# 关键配置 Kubernetes URL: https://k8s-api:6443 Kubernetes Namespace: jenkins Jenkins URL: http://jenkins-master:8080 Jenkins tunnel: jenkins-master:50000 # Pod Template 配置: Name: maven-pod Namespace: jenkins Labels: k8s-maven # Container Template: Name: maven Docker image: maven:3.9-eclipse-temurin-17 Command: cat Working directory: /home/jenkins/agent # 资源限制: CPU request: 1 CPU limit: 2 Memory request: 2Gi Memory limit: 4Gi # Volume: /root/.m2 → PVC(maven-cache)Pipeline 使用 K8s 动态 Agentpipeline { agent { kubernetes { label maven-pod 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 command: [cat] tty: true securityContext: privileged: true # 需要构建 Docker 镜像 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 clean package -DskipTests stash includes: target/*.jar, name: app-jar } } } stage(Docker Build) { steps { container(docker) { unstash app-jar sh docker build -t myapp:${BUILD_NUMBER} . sh docker push registry.com/myapp:${BUILD_NUMBER} } } } } }**踩坑提示**K8s 动态 Agent 的 Pod 默认有 5 分钟空闲超时。如果 Pipeline 中有长时间等待如等待人工审批Pod 会被回收导致 Pipeline 失败。在 Pod Template 中设置 idleMinutes: 30 延长超时时间。四、任务分发策略1. 标签表达式// AND 表达式同时拥有两个标签 agent { label java docker } // OR 表达式任一标签 agent { label java-build || go-build } // 排除表达式 agent { label build !e2e-test }2. 负载均衡Jenkins 内置的负载均衡策略| 策略 | 说明 | 配置方式 ||------|------|---------|| Round Robin | 轮询分发 | 默认 || Load | 优先选负载低的 | Node 配置 → Usage → Use this node as much as possible || Specific | 指定节点 |agent { label agent-01 }|3. 优先级队列// 在 Job 配置中设置优先级 properties([ buildDiscarder(logRotator(numToKeepStr: 20)), [$class: JiraProjectProperty], pipelineTriggers([cron(daily)]) ]) // 通过 Priority Sorter 插件设置优先级 // 安装 Priority Sorter Plugin 后 // Manage Jenkins → System → Priority Sorter // → Priority Strategy → Absolute Priority // → Job Group: // - deploy-* → Priority 1 (最高) // - build-* → Priority 5 // - test-* → Priority 104. 资源互斥避免多个 Job 同时操作同一资源pipeline { agent any options { // 同一资源组同时只允许一个构建 lock(resource: production-deploy, inversePrecedence: true) } stages { stage(Deploy) { steps { sh kubectl apply -f deploy/ -n prod } } } }五、监控 Agent 健康状态健康检查脚本#!/bin/bash # 定期检查所有 Agent 的磁盘空间 for agent in $(java -jar jenkins-cli.jar -s http://localhost:8080 list-nodes 2/dev/null | awk {print $1}); do DISK_USAGE$(java -jar jenkins-cli.jar -s http://localhost:8080 node $agent run-script println df -h.execute().text 2/dev/null | grep /$ | awk {print $5} | tr -d %) if [ $DISK_USAGE -gt 80 ]; then echo WARNING: Agent $agent disk usage: ${DISK_USAGE}% # 推送到 Prometheus echo jenkins_agent_disk_usage{agent\$agent\} $DISK_USAGE | curl --data-binary - http://pushgateway:9091/metrics/job/jenkins-agent fi doneAgent 自动清理# 定时清理 Agent 上的旧构建产物 #!/bin/bash # 在每个 Agent 上配置 crontab find /home/jenkins/workspace -mindepth 1 -maxdepth 1 -type d -mtime 7 -exec rm -rf {} \; find /tmp -name jenkins* -mtime 1 -exec rm -f {} \; docker system prune -f --filter until24h六、本篇要点回顾1. Agent 按技术栈任务类型规划标签Pipeline 中用标签精确匹配2. 跨节点传递产物用stash/unstash不能依赖工作空间3. K8s 动态 Agent 按需创建、用完即删配合 PVC 缓存依赖4.lock指令实现资源互斥防止多个 Job 同时操作生产环境5. 监控 Agent 磁盘和状态定期清理旧产物下一篇预告《插件生态必装插件清单与安全加固》——盘点 Jenkins 生态中真正好用的插件以及如何避免插件地狱。
返回列表