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
相关推荐
微风◝6 小时前
AlmaLinux9-网络管理篇-更改网络接口名称
linux·运维·网络
tianyuanwo6 小时前
Ansible构建节点管理:Koji与Mock构建节点的自动化运维实践
运维·自动化·ansible
怀旧,6 小时前
【Linux系统编程】10. 进程控制(下)
linux·运维·服务器
Evan芙6 小时前
DNS域名三级结构,DNS服务工作原理,涉及递归和迭代查询原理总结
linux·运维·服务器
CIb0la6 小时前
Microsoft Excel 已经40岁了
运维·智能手机·生活
apihz6 小时前
随机英文姓名生成API接口详细教程:免费、简单、高效
android·java·运维·服务器·开发语言
听风吟丶7 小时前
云原生智能告警与故障自愈实战:从被动响应到主动运维
运维·云原生
石牌桥网管7 小时前
Linux ip 命令教程
linux·运维·tcp/ip
深圳安锐科技有限公司7 小时前
工程安全自动化监测VS人工检测:全方位解析结构健康监测的必然趋势
运维·安全·自动化·自动化监测·结构健康监测