Ravindra BagaleCourses & study guides मराठी

Chapter 27: Jenkins Agents

27.1 Labels

Why: the problem

Think of Swiggy. It has one Jenkins controller and more than a hundred build jobs. Some jobs need Node.js 20. Some need Java 17 and Maven. Some need Docker. Some need a GPU for model tests. If every job runs on the controller, three bad things happen. First, the controller CPU hits 100 percent and the Jenkins web page becomes slow for everyone. Second, one job installs a tool that breaks another job. Third, a build script can read the controller disk, where all secrets and job configs live. So Jenkins splits the work. The controller only plans and shows results. Agents are separate machines that run the builds. A label is a simple tag on an agent, like node20 or maven or docker. The Jenkinsfile asks for a label, and Jenkins sends the build to any online agent with that label. In this lesson you will add labels, use them in a Jenkinsfile, combine labels with and, or and not, and set the controller to run zero builds.

What we will build

You will run a lab Jenkins controller in Docker. You will add two agents, one with labels linux node20 and one with labels linux maven docker. You will write three Jenkinsfiles that pick agents by label, by label expression, and per stage. Finally you will set the built-in node to 0 executors and prove that builds still run, but only on agents.

What: every term in plain English

  • Controller — The main Jenkins server. It stores jobs, shows the web page and schedules builds. It should not run builds.
  • Agent — A separate machine or container that runs build steps for the controller. Old name: slave or node.
  • Node — Jenkins word for any machine that can run builds, including the controller itself, called the built-in node.
  • Executor — One build slot on a node. An agent with 2 executors can run 2 builds at the same time.
  • Label — A tag on an agent, like linux, node20 or docker. Jobs ask for labels, not machine names.
  • Label expression — A small rule like linux and docker, or maven || gradle, or !windows.
  • Usage mode — Agent setting. Use this node as much as possible, or Only build jobs with label expressions matching this node.
  • Remote root directory — The folder on the agent where Jenkins keeps workspaces, like /home/jenkins/agent.
Start a lab controller Get the first admin password Open the Nodes page Give labels Check labels from the script console Use the label in a Jenkinsfile Set built-in executors to 0
Jenkinsfile label to the right agent, top to bottom

How: step by step

  1. Start a lab controller

    docker network create jenkins
    docker run -d --name jenkins --network jenkins -p 8080:8080 -p 50000:50000 -v jenkins_home:/var/jenkins_home jenkins/jenkins:lts-jdk17
    

    What it does: Starts Jenkins with the web port 8080 and agent port 50000.

    Output

    3f9a1c... (container ID)
    
  2. Get the first admin password

    docker exec jenkins cat /var/jenkins_home/secrets/initialAdminPassword
    

    What it does: Prints the one-time unlock password.

    Output

    5b2e8c0d4f... (32 characters)
    
  3. Open the Nodes page

    Manage Jenkins > Nodes > New Node > name agent-node20 > Permanent Agent
    

    What it does: Creates the agent entry on the controller.

    Output

    Page shows agent-node20 (offline)
    
  4. Give labels

    Labels: linux node20   Executors: 2   Remote root: /home/jenkins/agent   Usage: Only build jobs with label expressions matching this node
    

    What it does: Space separated labels. The strict usage mode stops random jobs landing here.

    Output

    Saved
    
  5. Check labels from the script console

    Manage Jenkins > Script Console > Jenkins.instance.nodes.each { println it.nodeName + " -> " + it.labelString }
    

    What it does: Lists every agent and its labels.

    Output

    agent-node20 -> linux node20
    agent-maven -> linux maven docker
    
  6. Use the label in a Jenkinsfile

    agent { label 'node20' }
    

    What it does: The whole pipeline runs on an agent with node20.

    Output

    Running on agent-node20 in /home/jenkins/agent/workspace/badge-node
    
  7. Set built-in executors to 0

    Manage Jenkins > Nodes > Built-In Node > Configure > Number of executors: 0
    

    What it does: The controller now runs no builds at all.

    Output

    Built-In Node: 0 executors
    

Example 1: Pick one agent by label for the whole pipeline

Stack. Jenkins LTS, permanent Linux agent, Node.js 20

Goal. Pick one agent by label for the whole pipeline.

Jenkinsfile

pipeline {
  agent { label 'node20' }
  options { timestamps() }
  stages {
    stage('Where am I') {
      steps {
        sh 'hostname'
        echo "Node name: ${env.NODE_NAME}"
        echo "Labels: ${env.NODE_LABELS}"
        sh 'node --version && npm --version'
      }
    }
    stage('Test') {
      steps {
        sh 'npm ci'
        sh 'npm test'
      }
    }
  }
}

What each line does

  • agent { label 'node20' } — Send the whole build to any online agent that has the node20 label.
  • options { timestamps() } — Adds a clock time to every console line. Needs the Timestamper plugin.
  • env.NODE_NAME — Built-in variable with the name of the agent that runs the build.
  • env.NODE_LABELS — All labels of that agent, space separated.
  • sh 'node --version' — Proves the right tool is installed on this agent.
  • sh 'npm ci' — Clean install of packages from package-lock.json.

Green output

Running on agent-node20 in /home/jenkins/agent/workspace/badge-node
[Pipeline] stage (Where am I)
+ hostname
ip-10-0-1-25
Node name: agent-node20
Labels: agent-node20 linux node20
+ node --version
v20.15.1
10.7.0
[Pipeline] stage (Test)
+ npm ci
added 212 packages in 6s
+ npm test
Tests: 14 passed, 14 total
Finished: SUCCESS

Expected result. The build ran on agent-node20, not on the controller. Node and npm came from the agent.

Example 2: Use label expressions with and, or and not

Stack. Jenkins, two permanent agents

Goal. Use label expressions with and, or and not.

Jenkinsfile

pipeline {
  agent none
  stages {
    stage('Java build') {
      agent { label 'linux && maven' }
      steps {
        sh 'mvn -v | head -1'
        sh 'mvn -B -q package -DskipTests'
      }
    }
    stage('Image build') {
      agent { label 'docker && !windows' }
      steps { sh 'docker version --format "{{.Server.Version}}"' }
    }
    stage('Any JVM tool') {
      agent { label 'maven || gradle' }
      steps { echo "Picked ${env.NODE_NAME}" }
    }
  }
}

What each line does

  • agent none — No agent for the whole pipeline. Each stage picks its own.
  • label 'linux && maven' — Both labels must be on the agent.
  • label 'docker && !windows' — Has docker and does not have windows.
  • label 'maven || gradle' — Either label is fine.
  • mvn -B -q package — Batch mode, quiet output, build the jar.
  • Per stage agent — Each stage can go to a different machine. Files do not move by themselves; use stash for that (chapter 21).

Green output

[Pipeline] stage (Java build)
Running on agent-maven in /home/jenkins/agent/workspace/badge-java
+ mvn -v
Apache Maven 3.9.8
[Pipeline] stage (Image build)
Running on agent-maven in /home/jenkins/agent/workspace/badge-java
+ docker version --format {{.Server.Version}}
26.1.4
[Pipeline] stage (Any JVM tool)
Picked agent-maven
Finished: SUCCESS

Expected result. Each stage found a matching agent. Change maven to gradle in one agent and watch the third stage still pass.

Example 3: Prove the controller runs zero builds

Stack. Jenkins Script Console

Goal. Prove the controller runs zero builds.

check-executors.groovy

// Manage Jenkins > Script Console
def j = Jenkins.instance
println "Built-in executors: " + j.numExecutors
j.computers.each { c ->
  println c.name.padRight(16) + " online=" + !c.offline + " executors=" + c.numExecutors + " labels=" + c.node.labelString
}

Jenkinsfile (bad on purpose)

pipeline {
  agent { label 'built-in' }
  stages { stage('x') { steps { echo 'never runs' } } }
}

What each line does

  • j.numExecutors — Number of executors on the built-in node. Should be 0.
  • j.computers — Every node Jenkins knows, with live status.
  • c.offline — True when the agent is not connected.
  • label 'built-in' — The label of the controller itself. With 0 executors this build waits forever.
  • Abort it — Cancel the stuck build from the queue. This proves the controller is protected.

Green output

Built-in executors: 0
                 online=true executors=0 labels=
agent-node20     online=true executors=2 labels=linux node20
agent-maven      online=true executors=2 labels=linux maven docker

(bad Jenkinsfile)
Still waiting to schedule task
Waiting for next available executor on 'built-in'

Expected result. The controller has 0 executors. Any job that asks for it waits. Real jobs go to agents only.

Verify: did it work?

  1. Count builds per agent

    Manage Jenkins > Nodes > agent-node20 > Build History
    

    What it does: Shows only builds that ran on this agent.

    Output

    badge-node #12  agent-node20  SUCCESS
    
  2. Label page

    http://localhost:8080/label/node20/
    

    What it does: Shows all agents with this label and how busy they are.

    Output

    Nodes: agent-node20 (idle)
    

When it is red 1

Waiting for next available executor on 'node20'
There are no nodes with the label 'node20'

Cause. No agent has this label, or the label is misspelled, like node-20.

Fix, step by step

  1. Open Manage Jenkins > Nodes and read the labels.
  2. Fix the spelling in the agent or the Jenkinsfile.
  3. Open /label/node20/ to confirm one agent appears.

When it is red 2

Waiting for next available executor on 'agent-node20'
agent-node20 is offline

Cause. The agent has the label but is not connected.

Fix, step by step

  1. Open the agent page and read the log.
  2. Restart the agent service (lesson 27.2).
  3. Check port 50000 or SSH port 22 is open.

When it is red 3

npm: command not found

Cause. The build landed on an agent without Node, because the label was too loose, like linux.

Fix, step by step

  1. Use a specific label, like node20.
  2. Put tool labels only on agents that really have the tool.
  3. Print node --version as the first step.

Cleanup

  1. Remove a lab agent

    Manage Jenkins > Nodes > agent-node20 > Delete Agent
    

    What it does: Removes the agent entry. Workspaces on the machine stay.

    Output

    agent-node20 deleted
    
  2. Stop the lab controller

    docker rm -f jenkins && docker volume rm jenkins_home && docker network rm jenkins
    

    What it does: Deletes the lab completely.

    Output

    jenkins
    jenkins_home
    jenkins
    

Ravindra Bagale's Tip

Controller var build nako, executors 0 theva. Label spelling Jenkinsfile ani agent madhe same pahije. Lakshat theva!

Practice tasks

Easy Label two agents

Why: Labels are the base of agent routing.

What to do: Give one agent node20 and another maven.

How:
  1. Nodes > Configure > Labels.

Check: Both appear on their /label/ pages.

Medium Label expression stage

Why: Real pipelines mix tools.

What to do: Write a stage with docker && !windows.

How:
  1. agent none at top.
  2. Stage level agent.

Check: Console shows the matching agent.

Hard Zero controller executors

Why: The controller holds secrets.

What to do: Set built-in executors to 0 and fix any job that breaks.

How:
  1. Change the setting.
  2. Run all jobs once.
  3. Give each a label.

Check: All jobs pass on agents.

Easy Say Jenkins agents and labels in two lines

Why: If you can say it simply, you understand it. Juniors and interviewers want the short version first.

What to do: Write two short lines about Jenkins agents and labels for a fresher who knows only Linux basics.

How:
  1. Write what problem it solves.
  2. Write the one command or menu you use for it.
  3. Read it aloud to a friend.

Check: A fresher understands it without asking a question.

Easy Start a fresh lab Jenkins

Why: Practice needs a throwaway Jenkins. If you break it, you delete it and start again.

What to do: Run Jenkins LTS in Docker with a named volume.

How:
  1. docker volume create jenkins_home
  2. docker run -d --name jenkins -p 8080:8080 -v jenkins_home:/var/jenkins_home jenkins/jenkins:lts-jdk17
  3. docker exec jenkins cat /var/jenkins_home/secrets/initialAdminPassword

Check: The Jenkins unlock page opens on localhost:8080.

Medium Break it on purpose

Why: You must know the red message by face. During an outage there is no time to read slowly.

What to do: Cause one error from the "When it is red" part of this lesson and fix it.

How:
  1. Follow the error section.
  2. Copy the exact message into your notes.
  3. Write the fix in one line.

Check: You fixed it using only the steps, without searching the web.

Medium Write a one-page runbook

Why: At 2 a.m. nobody remembers where a file lives. A short page saves the on-call person.

What to do: Write a runbook page for this lesson.

How:
  1. Title, when to use, exact command, how to check, how to undo.

Check: A teammate can follow it alone.

Medium Repeat it on a cloud VM

Why: A laptop is not a server. Real Jenkins runs on EC2 or a company VM.

What to do: Do the main steps of this lesson again on a small Ubuntu 22.04 EC2 instance.

How:
  1. Launch t3.small with 20 GB disk.
  2. Open port 22 only to your IP.
  3. Repeat the steps and compare the output.

Check: Same green output on the VM as on your laptop.

Hard Explain it like an interview

Why: Interviewers want real stories, not definitions.

What to do: Record a 60 second answer about this lesson.

How:
  1. Say the problem, the command you ran, and one error you hit.

Check: Your answer has a real command and a real error message.

Hard Draw the flow top to bottom

Why: A drawing shows who talks to whom and in what order.

What to do: Draw this lesson as boxes from top to bottom.

How:
  1. Start at the developer push, go through the controller and agent, end at the result.

Check: Each box matches a real thing you saw on screen.

Homework: try at home

Try at home

At home, make two agents with different labels. Write one Jenkinsfile with agent none and three stages that each pick a different label expression. Then set built-in executors to 0 and take a screenshot of the console showing the agent name in every stage.

Recap

  • The controller schedules; agents build.
  • Labels are tags; Jenkinsfiles ask for labels.
  • Label expressions use &&, || and !.
  • Use strict usage mode on special agents.
  • Set the built-in node to 0 executors.

FAQ

Can one agent have many labels?

Yes. Separate them with spaces, like linux node20 docker.

Is the agent name also a label?

Yes. Every agent has its own name as a label, but use tool labels instead.

How many executors per agent?

Usually one per CPU core for light builds, fewer for heavy Java or Docker builds.

Do agents need Jenkins installed?

No. They need Java and the small agent.jar, or SSH with Java.

What happens if two agents share a label?

Jenkins picks any free one. That gives you simple load balancing.

Interview questions

  1. Why should the controller have zero executors?

    Builds on the controller can read its home folder with secrets and job configs, and heavy builds slow the UI. Agents isolate the work.

  2. What is a Jenkins label?

    A tag on an agent that jobs use to pick the kind of machine they need, for example node20 or docker.

  3. How do you send one stage to a different machine?

    Use agent none at the pipeline level and an agent block with a label inside each stage.

  4. A build waits forever with no nodes with the label. What do you check?

    Label spelling, whether any agent has that label, and whether that agent is online.

  5. What is an executor?

    A build slot on a node. Executors decide how many builds run at once on that machine.

Quick quiz

Q1. Where should builds run, controller or agents?

Agents. The controller should have 0 executors.

Q2. What does a label do?

It lets a job ask for a kind of agent instead of a machine name.

Q3. What does label 'linux && docker' mean?

The agent must have both labels.

Q4. Which variable prints the agent name?

env.NODE_NAME.

Q5. What does agent none do?

No agent for the whole pipeline, so each stage picks one.

Samajla ka?

Ravi Sir's Cards for this lesson

मराठी cards