第47章|Jenkins Agents:静态节点、容器化 agent 与 Kubernetes plugin

控制器负责“接单”,agent 才是拧螺丝的手。本章从长期驻场的静态节点,走到用完即焚的容器, 再到 Kubernetes 上弹性伸缩的 Pod agent——你会理解 label 如何把任务路由到对的池子, 以及为何可重复环境弹性成本往往成对出现。

Static

Persistent VMs

  • SSH / JNLP
  • executors
  • pet vs cattle
Docker

Image per build

  • agent docker
  • cache volumes
  • dinD caution
Kubernetes

Pod agents

  • Pod template
  • JNLP sidecar
  • namespace quota

1. Agent 模型:label、executor、workspace

每个 agent(在 UI 里常叫 Node)有一组 labels,流水线用 agent { label 'linux && jdk17' } 或等价表达式挑选。 节点上的 executors 决定并行构建槽位;每个构建拿到独立 workspace 目录。 控制器把任务排进队列,agent 拉活执行——队列过长通常意味着 agent 不足或某类 job 占满槽位。

Queue → labeled agents → executors Controller build queue FIFO + label match blocked → waiting for label Agent pool linux-docker ex 1 ex 2 idle windows-msbuild ex 1 idle Static agents are “pets”: patch OS, clear workspaces, watch disk Mis-sized executors → head-of-line blocking for heavy jobs
图 1:队列不是无限魔法;label 匹配不到就会一直等——容量规划要按标签维度做。

2. 静态 agent:可靠、可预测、但要喂养

长期运行的 VM / 物理机适合重活、GPU、许可证绑定在某台机器等场景。连接方式常见:SSH Launcher(控制器主动连)、 JNLP / WebSocket(agent 主动连出)。运维要管:系统补丁、磁盘、全局工具版本漂移、并发构建争用同一套缓存。

3. 容器化 agent:镜像即环境契约

使用 Docker Pipeline 等能力时,可在 agent { docker { ... } } 中指定镜像与参数,让每一步在干净或近干净的文件系统里跑, 显著降低“昨天还能编、今天不能编”的漂移。注意 /var/run/docker.sock 挂载(Docker-in-Docker)带来的特权与逃逸面,仅在有治理时使用。

pipeline {
  agent {
    docker {
      image 'maven:3.9-eclipse-temurin-17'
      args '-v $HOME/.m2:/root/.m2'
    }
  }
  stages {
    stage('Build') {
      steps { sh 'mvn -B -DskipTests package' }
    }
  }
}
缓存策略:挂载宿主目录做依赖缓存会提速,但可能把“脏状态”在构建间传递——要明确可接受性与清理策略。
Docker agent: image-bound workspace Docker host (agent) build container FROM maven:… reproducible toolchain ephemeral FS (usually) isolate Trade-offs ✓ consistent deps ✓ easy matrix (switch image) ⚠ socket mount = high trust ⚠ image pull / registry rate limits
图 2:容器把“编译环境”钉在镜像上;挂载 docker.sock 是把双刃剑。

4. Kubernetes plugin:Pod 即 agent

在 K8s 集群里,Jenkins 为每个构建(或每个 stage)调度一个 Pod:通常包含 JNLP / inbound 容器负责与控制器通信, 以及一个或多个 build 容器执行 sh。通过 PodTemplate 声明镜像、资源请求/上限、卷、节点选择等。 平台组要配置:命名空间、ServiceAccount、镜像拉取凭据、ResourceQuota、网络策略(是否允许出公网拉依赖)。

// Declarative-style sketch (YAML details vary by plugin version)
pipeline {
  agent {
    kubernetes {
      yaml '''
        apiVersion: v1
        kind: Pod
        spec:
          containers:
          - name: maven
            image: maven:3.9-eclipse-temurin-17
            command: ["sleep"]
            args: ["99d"]
      '''
    }
  }
  stages {
    stage('Build') {
      steps { container('maven') { sh 'mvn -B package' } }
    }
  }
}
Kubernetes cloud: one pod per build (typical) Jenkins controller schedules pod via K8s API kubernetes { yaml … } Namespace: ci-jenkins Pod: build-42-xyz jnlp / inbound connects to controller build maven / node / … sidecar docker-dind · cache requests/limits · SA · imagePullSecrets · pod quota
图 3:把集群当成“agent 工厂”;每个 Pod 是独立沙箱,失败可回收、成功可水平扩展。

5. 选型对照

形态 优点 代价
静态 VM 简单心智、适合特殊硬件 漂移、维护、扩展慢
Docker on agent 镜像即环境、易矩阵 宿主机 Docker 信任、IO 性能
K8s Pod 弹性、资源隔离、配额 集群与插件运维复杂度高
pet servers cattle pods progressive adoption → Static Docker Kubernetes
图 4:从“养宠物”到“牧群”——多数组织混用:核心链路用 K8s,特殊任务用静态。

6. 本章清单

  1. 盘点现有 label 与 executor 利用率;找出长期排队或闲置池。
  2. 为一个项目试验 agent { docker { … } },对比与裸机 agent 的差异。
  3. 若在 K8s 上:定义命名空间配额、ServiceAccount、镜像拉取策略与资源 request/limit。
  4. 评估 Docker-in-Docker 是否必需;若必须,收紧权限与审计。
  5. 预告下一章:agent 能拿到什么凭证、如何加固 Jenkins 与供应链。
← 上一章:共享库 下一章:Jenkins 安全 →