Jenkins 多语言 Agent 完整部署教程

📋 前置条件

  • 已安装 Docker 和 Docker Compose
  • Linux/Mac 环境(或 WSL2)
  • 有一个运行中的 Jenkins 实例
  • SSH 密钥对用于部署(可选但建议)

🏗️ 第一步:创建项目目录结构

bash 复制代码
# 进入你的工作目录,比如
cd /home

# Jenkins 主目录
mkdir -p jenkins-agents/{jenkins-home,agent-node,agent-java-17,agent-java-21,jenkins-cache/{pnpm-store,m2}}

# 各 agent 的工作目录
mkdir -p jenkins-agents/agent-node/work
mkdir -p jenkins-agents/agent-java-17/work
mkdir -p jenkins-agents/agent-java-21/work

# 查看目录结构
tree -L 2
# 或者用 ls -la
ls -la

目录结构应该如下:

bash 复制代码
jenkins-agents/
    ├── agent-java-17
    │   ├── Dockerfile
    │   ├── start-agent.sh
    │   └── work/
    ├── agent-java-21
    │   ├── Dockerfile
    │   ├── start-agent.sh
    │   └── work/
    ├── agent-node
    │   ├── Dockerfile
    │   ├── start-agent.sh
    │   └── work/
    ├── jenkins-cache/
    │   ├── m2/
    │   └── pnpm-store/
    ├── jenkins-home/
    ├── .env
    └── docker-compose.yml

🔧 第二步:配置 .env 文件

jenkins-agents 目录下创建 .env 文件:xxxxxxxxxxxxxxxxxxxxxxxx,要在 Jenkins 管理界面创建节点中获取,当前步骤先用占位符

bash 复制代码
cat > .env << 'EOF'
# Jenkins 基础配置
JENKINS_URL=http://jenkins:8080

# Node.js agent Secret(从 Jenkins 获取)
JENKINS_SECRET_NODE=xxxxxxxxxxxxxxxxxxxxxxxx

# Java 17 agent Secret(从 Jenkins 获取)
JENKINS_SECRET_JAVA_17=xxxxxxxxxxxxxxxxxxxxxxxx

# Java 21 agent Secret(从 Jenkins 获取)
JENKINS_SECRET_JAVA_21=xxxxxxxxxxxxxxxxxxxxxxxx

# 时区配置
TZ=Asia/Shanghai
EOF

替换所有 Secret 值为你在 Jenkins 中获取的真实值。


📝 第三步:创建各 Agent 的 Dockerfile

3.1.1 创建 Node.js Agent Dockerfile

bash 复制代码
cat > agent-node/Dockerfile << 'EOF'
# 基础镜像:包含 JDK 21
FROM eclipse-temurin:21-jdk

# 时区
ENV TZ=Asia/Shanghai
RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone

# 常用工具
RUN apt-get update && apt-get install -y --no-install-recommends \
    git curl unzip zip bash sudo procps openssh-client \
    && rm -rf /var/lib/apt/lists/*

# Node.js 安装
ENV NODE_VERSION=24.1.0
ENV NODE_DIST_URL=https://mirrors.aliyun.com/nodejs-release/v${NODE_VERSION}/node-v${NODE_VERSION}-linux-x64.tar.gz
RUN curl -fsSL $NODE_DIST_URL -o /tmp/node.tar.gz \
    && tar -xzf /tmp/node.tar.gz -C /opt \
    && rm /tmp/node.tar.gz
ENV NODE_HOME=/opt/node-v${NODE_VERSION}-linux-x64
ENV PATH=$NODE_HOME/bin:$PATH

# pnpm 安装
RUN npm config set registry https://registry.npmmirror.com
RUN npm install -g pnpm

# Jenkins agent 工作目录
ENV JENKINS_AGENT_WORKDIR=/home/jenkins/agent
RUN mkdir -p $JENKINS_AGENT_WORKDIR && chmod -R 777 $JENKINS_AGENT_WORKDIR
WORKDIR $JENKINS_AGENT_WORKDIR

# 拷贝启动脚本
COPY start-agent.sh /home/jenkins/start-agent.sh
RUN chmod +x /home/jenkins/start-agent.sh

# 默认执行启动脚本
ENTRYPOINT ["/home/jenkins/start-agent.sh"]
EOF

3.1.2 创建 Node.js Agent start-agent.sh

bash 复制代码
cat > agent-node/start-agent.sh << 'EOF'
#!/bin/bash
set -e

echo "等待 Jenkins 启动..."
until curl -sf "$JENKINS_URL/login" > /dev/null; do
    sleep 3
done

echo "Jenkins 已就绪,下载 agent.jar..."
curl -sSf "$JENKINS_URL/jnlpJars/agent.jar" -o agent.jar

echo "启动 Jenkins Agent..."
exec java -jar agent.jar \
    -url "$JENKINS_URL" \
    -secret "$JENKINS_SECRET" \
    -name "$JENKINS_AGENT_NAME" \
    -webSocket \
    -workDir "$JENKINS_AGENT_WORKDIR"

EOF

3.2.1 创建 Java 17 Agent Dockerfile

bash 复制代码
cat > agent-java-17/Dockerfile << 'EOF'
# 基础镜像:包含 JDK 17
FROM eclipse-temurin:17-jdk

# 时区
ENV TZ=Asia/Shanghai
RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone

# 常用工具
RUN apt-get update && apt-get install -y --no-install-recommends \
    git curl unzip zip bash sudo procps openssh-client \
    && rm -rf /var/lib/apt/lists/*

# Maven
ENV MAVEN_VERSION=3.9.11
ENV MAVEN_DOWNLOAD_URL=https://mirrors.tuna.tsinghua.edu.cn/apache/maven/maven-3/$MAVEN_VERSION/binaries/apache-maven-$MAVEN_VERSION-bin.tar.gz
RUN curl -fsSL $MAVEN_DOWNLOAD_URL | tar -xz -C /opt
ENV MAVEN_HOME=/opt/apache-maven-$MAVEN_VERSION
ENV PATH=$MAVEN_HOME/bin:$PATH

# Gradle
ENV GRADLE_VERSION=9.2.1
ENV GRADLE_DOWNLOAD_URL=https://mirrors.aliyun.com/gradle/distributions/v$GRADLE_VERSION/gradle-$GRADLE_VERSION-bin.zip
RUN curl -fsSL $GRADLE_DOWNLOAD_URL -o /tmp/gradle.zip \
    && unzip /tmp/gradle.zip -d /opt && rm /tmp/gradle.zip
ENV GRADLE_HOME=/opt/gradle-$GRADLE_VERSION
ENV PATH=$GRADLE_HOME/bin:$PATH

# Jenkins agent 工作目录
ENV JENKINS_AGENT_WORKDIR=/home/jenkins/agent
RUN mkdir -p $JENKINS_AGENT_WORKDIR && chmod -R 777 $JENKINS_AGENT_WORKDIR
WORKDIR $JENKINS_AGENT_WORKDIR

# 拷贝启动脚本
COPY start-agent.sh /home/jenkins/start-agent.sh
RUN chmod +x /home/jenkins/start-agent.sh

# 默认执行启动脚本
ENTRYPOINT ["/home/jenkins/start-agent.sh"]
EOF

3.2.2 创建 Java 17 start-agent.sh

bash 复制代码
cat > agent-java-17/start-agent.sh << 'EOF'
#!/bin/bash
set -e

echo "等待 Jenkins 启动..."
until curl -sf "$JENKINS_URL/login" > /dev/null; do
    sleep 3
done

echo "Jenkins 已就绪,下载 agent.jar..."
curl -sSf "$JENKINS_URL/jnlpJars/agent.jar" -o agent.jar

echo "启动 Jenkins Agent..."
exec java -jar agent.jar \
    -url "$JENKINS_URL" \
    -secret "$JENKINS_SECRET" \
    -name "$JENKINS_AGENT_NAME" \
    -webSocket \
    -workDir "$JENKINS_AGENT_WORKDIR"

EOF

3.3.1 创建 Java 21 Agent Dockerfile

bash 复制代码
cat > agent-java-21/Dockerfile << 'EOF'
# 基础镜像:包含 JDK 21
FROM eclipse-temurin:21-jdk

# 时区
ENV TZ=Asia/Shanghai
RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone

# 常用工具
RUN apt-get update && apt-get install -y --no-install-recommends \
    git curl unzip zip bash sudo procps openssh-client \
    && rm -rf /var/lib/apt/lists/*

# Maven
ENV MAVEN_VERSION=3.9.11
ENV MAVEN_DOWNLOAD_URL=https://mirrors.tuna.tsinghua.edu.cn/apache/maven/maven-3/$MAVEN_VERSION/binaries/apache-maven-$MAVEN_VERSION-bin.tar.gz
RUN curl -fsSL $MAVEN_DOWNLOAD_URL | tar -xz -C /opt
ENV MAVEN_HOME=/opt/apache-maven-$MAVEN_VERSION
ENV PATH=$MAVEN_HOME/bin:$PATH

# Gradle
ENV GRADLE_VERSION=9.2.1
ENV GRADLE_DOWNLOAD_URL=https://mirrors.aliyun.com/gradle/distributions/v$GRADLE_VERSION/gradle-$GRADLE_VERSION-bin.zip
RUN curl -fsSL $GRADLE_DOWNLOAD_URL -o /tmp/gradle.zip \
    && unzip /tmp/gradle.zip -d /opt && rm /tmp/gradle.zip
ENV GRADLE_HOME=/opt/gradle-$GRADLE_VERSION
ENV PATH=$GRADLE_HOME/bin:$PATH

# Jenkins agent 工作目录
ENV JENKINS_AGENT_WORKDIR=/home/jenkins/agent
RUN mkdir -p $JENKINS_AGENT_WORKDIR && chmod -R 777 $JENKINS_AGENT_WORKDIR
WORKDIR $JENKINS_AGENT_WORKDIR

# 拷贝启动脚本
COPY start-agent.sh /home/jenkins/start-agent.sh
RUN chmod +x /home/jenkins/start-agent.sh

# 默认执行启动脚本
ENTRYPOINT ["/home/jenkins/start-agent.sh"]
EOF

3.3.2 创建 Java 21 start-agent.sh

bash 复制代码
cat > agent-java-21/start-agent.sh << 'EOF'
#!/bin/bash
set -e

echo "等待 Jenkins 启动..."
until curl -sf "$JENKINS_URL/login" > /dev/null; do
    sleep 3
done

echo "Jenkins 已就绪,下载 agent.jar..."
curl -sSf "$JENKINS_URL/jnlpJars/agent.jar" -o agent.jar

echo "启动 Jenkins Agent..."
exec java -jar agent.jar \
    -url "$JENKINS_URL" \
    -secret "$JENKINS_SECRET" \
    -name "$JENKINS_AGENT_NAME" \
    -webSocket \
    -workDir "$JENKINS_AGENT_WORKDIR"

EOF

验证所有 Dockerfile 已创建:

bash 复制代码
ls -la agent-*/Dockerfile

📦 第四步:创建 docker-compose.yml

bash 复制代码
cat > docker-compose.yml << 'EOF'
networks:
  jenkins-net:
    driver: bridge

services:
  # Jenkins 主节点
  jenkins:
    image: jenkins/jenkins:lts
    container_name: jenkins
    user: "1000:1000"
    networks:
      - jenkins-net
    ports:
      - "8080:8080"
      - "50000:50000"
    volumes:
      - ./jenkins-home:/var/jenkins_home
      - /var/run/docker.sock:/var/run/docker.sock
    environment:
      TZ: Asia/Shanghai
    restart: unless-stopped

  # Node.js agent
  agent-node:
    build:
      context: ./agent-node
      dockerfile: Dockerfile
    container_name: jenkins-agent-node
    networks:
      - jenkins-net
    env_file:
      - .env
    environment:
      JENKINS_URL: "http://jenkins:8080"
      JENKINS_AGENT_NAME: "node-agent"
      JENKINS_SECRET: "${JENKINS_SECRET_NODE}"
      TZ: Asia/Shanghai
    volumes:
      - ./agent-node/work:/home/jenkins/agent
      - ./jenkins-cache/pnpm-store:/root/.pnpm-store
      - /var/run/docker.sock:/var/run/docker.sock
    depends_on:
      - jenkins
    restart: unless-stopped

  # Java 17 agent
  agent-java-17:
    build:
      context: ./agent-java-17
      dockerfile: Dockerfile
    container_name: jenkins-agent-java-17
    networks:
      - jenkins-net
    env_file:
      - .env
    environment:
      JENKINS_URL: "http://jenkins:8080"
      JENKINS_AGENT_NAME: "java-agent-17"
      JENKINS_SECRET: "${JENKINS_SECRET_JAVA_17}"
      TZ: Asia/Shanghai
    volumes:
      - ./agent-java-17/work:/home/jenkins/agent
      - ./jenkins-cache/m2:/root/.m2
      - /var/run/docker.sock:/var/run/docker.sock
    depends_on:
      - jenkins
    restart: unless-stopped

  # Java 21 agent
  agent-java-21:
    build:
      context: ./agent-java-21
      dockerfile: Dockerfile
    container_name: jenkins-agent-java-21
    networks:
      - jenkins-net
    env_file:
      - .env
    environment:
      JENKINS_URL: "http://jenkins:8080"
      JENKINS_AGENT_NAME: "java-agent-21"
      JENKINS_SECRET: "${JENKINS_SECRET_JAVA_21}"
      TZ: Asia/Shanghai
    volumes:
      - ./agent-java-21/work:/home/jenkins/agent
      - ./jenkins-cache/m2:/root/.m2
      - /var/run/docker.sock:/var/run/docker.sock
    depends_on:
      - jenkins
    restart: unless-stopped

EOF

🔐 第五步:设置文件权限

bash 复制代码
# 切换到 jenkins-agents 目录
cd /home/jenkins-agents

# 设置所有者(根据你的用户调整)
sudo chown -R 1000:1000 jenkins-home
sudo chown -R 1000:1000 jenkins-cache

# 设置权限
sudo chmod -R 755 jenkins-home
sudo chmod -R 755 jenkins-cache

# 创建必要的子目录权限
sudo chmod -R 777 jenkins-cache/pnpm-store
sudo chmod -R 777 jenkins-cache/m2
sudo chmod -R 777 jenkins-cache/docker-cache

# 验证权限
ls -la | grep jenkins

如果你用的是当前用户(非 root):

bash 复制代码
# 如果 jenkins-agents 在你的用户目录下
chmod -R 755 jenkins-home
chmod -R 755 jenkins-cache
chmod -R 777 jenkins-cache/pnpm-store
chmod -R 777 jenkins-cache/m2
chmod -R 777 jenkins-cache/docker-cache

🚀 第六步:启动所有服务

bash 复制代码
# 进入项目目录
cd /home/jenkins-agents

# 构建所有镜像(第一次运行)
docker compose build

# 启动所有服务
docker compose up -d

# 查看启动日志
docker compose logs -f

# 检查所有容器状态
docker compose ps

预期输出:

bash 复制代码
NAME                      STATUS
jenkins                   Up 2 minutes
jenkins-agent-node        Up 1 minute
jenkins-agent-java-17     Up 1 minute
jenkins-agent-java-21     Up 1 minute

🔐 第七步:生成 Jenkins Secret

7.1 在 Jenkins 管理界面创建节点

  1. 登录 Jenkins → 管理 Jenkins节点管理
  2. 点击 新建节点 3 次,创建:
    • node-agent
    • java-agent-17
    • java-agent-21

7.2 配置每个节点

node-agent 为例:

  • 节点名称node-agent
  • 类型 :选择 Permanent Agent
  • Remote root directory/home/jenkins/agent
  • 标签node (可选)
  • 启动方式 :选择 通过Java Web启动代理
  • 自定义 WorkDir 路径/home/jenkins/agent

点击保存后,你会看到一个连接命令,里面有 Secret,如下:

bash 复制代码
curl -sSf http://YOUR_JENKINS_URL/jnlpJars/agent.jar
java -jar agent.jar -url http://YOUR_JENKINS_URL -secret xxxxxxxxxxxxxxxxxxxxxxxx -name JENKINS_AGENT_NAME -webSocket -workDir JENKINS_AGENT_WORKDIR

提取 Secret 部分-secret 后面的那串)并记录下来。

7.3 重复创建其他 3 个节点,记录所有 Secret

7.4 将记录所有 Secret,替换 .env 文件中的 agent Secret,然后重启服务


✅ 第八步:验证节点连接

方式一:通过 Jenkins 管理界面

  1. 登录 Jenkins → 管理 Jenkins节点管理
  2. 检查所有 3 个节点是否显示为 "Online"
  3. 如果显示 "Offline",查看节点日志

方式二:通过命令行查看日志

bash 复制代码
# 查看 Node agent 日志
docker compose logs jenkins-agent-node

# 查看 Java 17 agent 日志
docker compose logs jenkins-agent-java-17

# 实时查看所有日志
docker compose logs -f

成功连接的日志示例:

bash 复制代码
jenkins-agent-node | 2024-12-10 10:15:30 ... Successfully connected

🧪 第九步:测试 Pipeline

在 Jenkins 创建一个测试 Pipeline,使用以下 Jenkinsfile:

groovy 复制代码
pipeline {
    agent {
        label 'node'  // 使用 node-agent
    }

    stages {
        stage('Test Node') {
            steps {
                sh 'node --version'
                sh 'pnpm --version'
                sh 'git --version'
            }
        }
    }
}

测试 Java 17

groovy 复制代码
pipeline {
    agent {
        label 'java-agent-17'
    }

    stages {
        stage('Test Java 17') {
            steps {
                sh 'java -version'
                sh 'mvn --version'
                sh 'gradle --version'
            }
        }
    }
}

🛠️ 常用命令

bash 复制代码
# 启动服务
docker compose up -d

# 停止服务
docker compose down

# 重启特定服务
docker compose restart jenkins-agent-node

# 查看实时日志
docker compose logs -f jenkins-agent-node

# 进入容器调试
docker compose exec jenkins-agent-node bash

# 重新构建镜像
docker compose build --no-cache

# 查看容器资源使用
docker stats

# 删除所有数据(谨慎!)
docker compose down -v

🔧 故障排查

问题 1:节点显示 "Offline"

bash 复制代码
# 查看连接日志
docker compose logs jenkins-agent-node

# 检查 .env 中的 Secret 是否正确
cat .env | grep JENKINS_SECRET

# 重启 agent
docker compose restart jenkins-agent-node

问题 2:构建时权限错误

bash 复制代码
# 检查缓存目录权限
ls -la jenkins-cache/

# 重新设置权限
chmod -R 777 jenkins-cache/m2
chmod -R 777 jenkins-cache/pnpm-store

问题 3:DNS 解析错误

编辑 .env,将 JENKINS_URL 改为你的真实地址:

bash 复制代码
# 如果 Jenkins 在外部
JENKINS_URL=http://192.168.1.100:8080

# 或使用 Docker 网络 DNS
JENKINS_URL=http://jenkins:8080

问题 4:Docker 权限错误

bash 复制代码
# 检查 docker.sock 挂载
docker compose exec jenkins-agent-docker ls -la /var/run/docker.sock

# 添加权限
docker compose exec jenkins-agent-docker chmod 666 /var/run/docker.sock

📊 完整检查清单

  • 创建了 jenkins-agents 目录及所有子目录
  • 在 Jenkins 创建了 3 个 JNLP 节点
  • 复制了所有 3 个 Secret 到 .env 文件
  • 创建了所有 3 个 Dockerfile
  • 创建了 docker-compose.yml
  • 设置了正确的文件权限
  • 运行 docker compose build 构建镜像
  • 运行 docker compose up -d 启动所有服务
  • 验证所有 3 个节点在 Jenkins 中显示为 "Online"
  • 成功运行了测试 Pipeline

📞 快速参考

任务 命令
启动所有服务 docker compose up -d
停止所有服务 docker compose down
查看服务状态 docker compose ps
查看日志 docker compose logs -f
进入容器 docker compose exec jenkins-agent-node bash
重建镜像 docker compose build
查看 .env 内容 cat .env
相关推荐
403240731 小时前
[Jetson/Ubuntu 22.04] 解决挂载 exFAT 硬盘报错 “unknown filesystem type“ 及只读权限问题的终极指南
linux·运维·ubuntu
零意@1 小时前
debian如何把新编译的内核镜像替换原来的内核
运维·debian·更新内核版本·linux内核版本更新·debian更新内核
Love丶伊卡洛斯1 小时前
Ubuntu 部署 STUN服务端
linux·运维·ubuntu
有毒的教程3 小时前
SaltStack 开源自动化运维工具详细介绍
运维·开源·saltstack
大房身镇、王师傅3 小时前
【VirtualBox】VirtualBox 7.1.6 RockyLinux10 配置增强功能 设置共享目录
运维·服务器·virtualbox·rockylinux10
betazhou3 小时前
rsync使用案例分析
linux·运维·服务器·rsync·同步数据
minglie15 小时前
谷歌浏览器搜索技巧
运维
脑子进水养啥鱼?5 小时前
Linux find 命令
linux·运维
曹天骄6 小时前
Cloudflare Worker 关联域名访问后出现301 / 308
运维·云计算
EverydayJoy^v^6 小时前
RH124简单知识点——第8章——配置和保护SSH
linux·运维·ssh