Build Agents, Distributed Builds, and Cloud Agents
What this domain covers
Scheduling, connectivity, and cleanliness. Expect questions on labels, launch methods, cloud provisioning, and what happens to a workspace when an agent is ephemeral.
Core rules
- Roles. The controller schedules and serves the UI; agents execute. Best practice sets the built-in node's executors to 0 so builds never run on the controller.
- Labels select capacity:
agent { label 'linux && jdk17' }. Labels are free text on nodes; an unmatched label leaves the build at "still waiting to schedule task" with no error. - Launch methods. SSH via the SSH Build Agents plugin (credential plus host-key strategy). Inbound - the agent connects out: fetch
agent.jarfrom/jnlpJars/agent.jarand runjava -jar agent.jar -jnlpUrl https://<jenkins>/computer/<name>/jenkins-agent.jnlp -secret <secret> -workDir /path. Protocols: JNLP4 on TCP 50000 by default, or WebSocket over the HTTP port when 50000 is blocked. Cloud plugins provision on demand. - Cloud agents. Kubernetes plugin: pod templates and container templates, where the pod must include a
jnlpcontainer so the agent can connect; tuneidleMinutes,instanceCap,activeDeadlineSeconds. Docker:agent { docker { image 'maven:3.9-eclipse-temurin-17' } }needs Docker on the agent plus the Docker Pipeline plugin. EC2 and Azure VM plugins work the same way. - Workspaces are per job per node. Ephemeral cloud agents discard them, so anything a later stage needs must travel via
stash/unstashor be archived. - Tool installers let
tools { maven 'maven-3.9' }provision configured tools on whichever agent runs the stage.
Worked example
A pipeline compiles in a container and then runs integration tests on a labelled VM. Use agent none; stage 1 with agent { docker { image 'maven:3.9-eclipse-temurin-17' } } produces target/app.jar; add stash name: 'app', includes: 'target/app.jar'; stage 2 uses agent { label 'vm-linux' } and unstash 'app'. Reasoning: the stages may land on different nodes with unrelated workspaces, and stashing is the supported way to carry files between them without polluting the build record with artifacts.
Traps
Declaring a label nobody has, so the job waits forever; assuming port 50000 is reachable when only 443 is open (switch to WebSocket); leaving controller executors enabled; expecting a Kubernetes pod to be reused after idleMinutes; omitting -workDir and filling a small partition; disabling SSH host-key verification in production.