Jenkins JNLP Agent
JNLP Agent(Java Network Launch Protocol Agent)是 Jenkins 中一种将 远程节点(Agent/Slave)连接到 Jenkins 主节点(Master/Controller)的方式。它允许你将构建任务分发到其他机器上执行,实现分布式构建,提升并发能力和资源利用率。
JNLP(Java Network Launch Protocol)是 Java 提供的一种机制,允许通过 Web 启动远程 Java 应用程序。
在 Jenkins 中,JNLP Agent 是一个运行在远程机器上的 Java 进程,通过 JNLP 协议连接到 Jenkins 主节点,并接收构建任务。
也称为 “Inbound Agent”(入站代理),因为是 Agent 主动连接 Master(与 SSH Agent 的“出站”方式相对)。
✅ 适合场景:
- 你无法从 Jenkins 主机直接 SSH 到构建机器(如 Windows 机器、容器、受限网络环境)。
- 构建节点在防火墙/NAT 后,只能主动向外连接。
- 需要临时启动的 Agent(如 Kubernetes Pod、Docker 容器)。
-
通过 Manage Jenkins -> Nodes -> New node -> Type: Permanent Agent 创建一个永久节点。
-
Jenkins 为主机生成一个唯一的 Agent 名称 和 密钥(secret)。
-
在目标机器上执行以下命令启动 Agent。
-
Agent 通过 HTTP/HTTPS 连接到 Jenkins 主节点,建立持久连接。
-
Jenkins 主节点可向该 Agent 分配 Job 构建任务。
⚠️ 注意:
agent.jar是 Jenkins 提供的客户端 JAR 文件,可从http://<jenkins-url>/jnlpJars/agent.jar下载。- 必须安装 Java 运行环境(JRE 或 JDK)在 Agent 机器上。
进入 Manage Jenkins -> Nodes -> New node
- Node name:build-node-01(节点名称)
- Type:选择 Permanent Agent (类型:永久代理)
- 配置:
- Number of executors:2 (并发构建数)
- Remote root directory:/data/jenkins/data (远程工作目录)
- Labels:agent(标签,用于 Pipeline 中
agent { label 'xxx' }调度) - Launch method:选择 Launch agent by connecting it to the controller



保存后,进入该节点页面,你会看到:
build-node-01
Built-In Node

点击 build-node-01,会给出相关的命令。

登录 Jenkins Agent 节点服务器,执行相关操作:
# 创建用户
# 注意: jenkins 用户的 home 目录不要设置在 /home 目录下 !!
# 原因: podman 打包的镜像保存在 ~/.local/share/containers 目录下, 会导致 / 或者 /home 空间不足
useradd -r -m -d /data/jenkins/home jenkins
# 创建目录
mkdir -p /data/jenkins/{app,data,log}
# 进入目录
cd /data/jenkins/app
# 创建密钥文件
echo ea388ed70f35857f98c23d73f8bc75b5f81a8ecef9ea93842ae4b6fae4c6a7b2 > secret-file
# 下载 JNLP Agent
curl -sO http://192.168.101.201:8200/jnlpJars/agent.jar
# 设置权限
chown -R jenkins:jenkins /data/jenkins
# 启动 JNLP Agent
# java -jar agent.jar -url http://192.168.101.201:8200/ -secret @secret-file -name "build-node-01" -webSocket -workDir "/data/jenkins/data"
# 创建服务
tee /etc/systemd/system/jenkins-agent.service <<'EOF'
[Unit]
Description=Jenkins Agent
After=network.target
[Service]
Type=simple
User=jenkins
Group=jenkins
# 工作目录
WorkingDirectory=/data/jenkins/app
# 启动命令
ExecStart=/usr/local/jdk/21.0.9/bin/java -jar agent.jar -url http://192.168.101.201:8200/ -secret @secret-file -name "build-node-01" -webSocket -workDir "/data/jenkins/data"
# 日志输出到文件
StandardOutput=append:/data/jenkins/log/run.log
StandardError=append:/data/jenkins/log/error.log
# 自动重启策略
Restart=always
RestartSec=5s
[Install]
WantedBy=multi-user.target
EOF
# 启动服务
systemctl daemon-reload
systemctl start jenkins-agent
systemctl status jenkins-agent
# ● jenkins-agent.service - Jenkins Agent
# Loaded: loaded (/etc/systemd/system/jenkins-agent.service; disabled; preset: disabled)
# Active: active (running) since Sat 2026-01-03 23:32:17 CST; 13s ago
# Main PID: 1456 (java)
# Tasks: 41 (limit: 209715)
# Memory: 59.5M (peak: 60.1M)
# CPU: 2.761s
# CGroup: /system.slice/jenkins-agent.service
# └─1456 /usr/local/jdk/21.0.9/bin/java -jar agent.jar -url http://192.168.101.201:8200/ -secret @secret-file -name build-node-01 -webSocket -workDir /data/jenkins/data
# Jan 03 23:32:17 node-202.server.com systemd[1]: Started Jenkins Agent.
# 创建服务
systemctl enable jenkins-agent
刷新 build-node-01 页面,查看节点状态

以相同的方式添加 build-node-02,最终结果:

回到 Nodes 页面,点击 Built-In Node,选择 Configure,确保 Number of executors 设置为 0。
# 允许用户在无登录状态下运行
loginctl enable-linger jenkins
# 设置密码
echo 'wR5zxK2R' | passwd --stdin jenkins
# 禁止 jenkins 用户通过 SSH 登录
echo 'DenyUsers jenkins' >> /etc/ssh/sshd_config.d/99-deny-users.conf
systemctl restart sshd
# 设置 sudo 权限
echo 'jenkins ALL=(ALL) NOPASSWD: /usr/bin/podman,/usr/bin/docker' >> /etc/sudoers.d/jenkins
chmod 400 /etc/sudoers.d/jenkins
# 设置 UID 和 GID
usermod --add-subuids 100000-165535 --add-subgids 100000-165535 jenkins
# 去重 & 排序
awk -F: '{ res[$1] = $0 } END { for (u in res) print res[u] }' /etc/subuid | sort | sudo tee /etc/subuid
awk -F: '{ res[$1] = $0 } END { for (u in res) print res[u] }' /etc/subgid | sort | sudo tee /etc/subgid
# 切换用户
su - jenkins
# 检查配置
cat ~/.config/containers/containers.conf
# 如果配置文件不存在, 创建配置文件
# 强制 Podman 使用默认的 ulimit, 避免它尝试去设置过高的值
# 将其设置为一个 Jenkins 进程允许的值 (通常 4096 是比较安全的)
mkdir -p ~/.config/containers
cat > ~/.config/containers/containers.conf <<'EOF'
[containers]
default_ulimits = [ "nofile=1024:4096" ]
EOF
# 重置 podman
podman system migrate
podman system reset -f
# 查看镜像
podman images
# 拉取镜像
HTTP_PROXY=http://192.168.101.200:1080 HTTPS_PROXY=http://192.168.101.200:1080 podman pull custom/jdk:21.0.9-0
如果 jenkins 用户执行
docker build始终有问题,则给 jenkins 用户创建 sudo 权限 ( /etc/sudoers.d/jenkins ),将docker build改为sudo docker build。
| 特性 | JNLP Agent | SSH Agent |
|---|---|---|
| 连接方向 | Agent -> Master(入站) | Master -> Agent(出站) |
| 防火墙友好 | ✅ 适合 NAT/防火墙后 | ❌ 需开放 SSH 端口 |
| 操作系统支持 | 跨平台(需 Java) | 主要 Linux(需 SSH 服务) |
| 启动方式 | 手动执行 Java 命令 | Jenkins 自动 SSH 登录启动 |
| 资源开销 | 需常驻 Java 进程 | 按需启动,更轻量(一次性 Agent) |
✅ 现代推荐:对于云环境或容器化场景,使用 Pod Template(Kubernetes Plugin)或 Docker Agent 更灵活,它们底层也常基于 JNLP。
| 问题 | 可能原因 | 解决方案 |
|---|---|---|
Connection refused |
Jenkins URL 不可达 | 检查网络、防火墙、Jenkins 是否运行 |
Invalid secret |
密钥错误或过期 | 重新复制 Secret,或在节点配置中点击 “Fix” |
Unsupported protocol |
Java 版本不兼容 | 使用 Java 8/11,避免 Java 17+(除非 Jenkins 支持) |
| Agent 频繁断开 | 网络不稳定 | 增加重连脚本,或改用更稳定连接方式 |
JNLP Agent 是 Jenkins 分布式构建的核心机制之一,特别适合:
- 无法被主节点直接访问的构建机器
- 需要灵活扩展构建资源的场景
- Windows 或混合环境构建
虽然配置略复杂(需手动启动 Java 进程),但它是实现 横向扩展 Jenkins 能力 的关键一环。