Skip to content

Jenkins-基础

简介

Jenkins 是一个开源的、可扩展的持续集成和持续交付 (CI/CD) 自动化服务器。它的核心价值在于通过流水线 (Pipeline) 将软件的构建、测试、部署等一系列过程自动化。

开发者写代码上传gitlab服务器上由jenkins帮我们到gitlab里面把最新代码拉取出来(clone),jenkins通过插件可以对拉取的代码完成自动化测试。测试完成后,可以自带把代码(编译,打包....)。创建一个共享目录,把打包的代码共享出去(比如NFS共享或者FTP共享)web1,web2这样的服务器就可以自动到jenkins共享里面下载代码,让用户访问

webhooks 钩子自动构建

第一步 GitLab配置

Admin —> Settings —> Network —> Outbound requests

设置允许通过网络钩子webhooks请求,勾选如下两项

  • Allow requests to the local network from webhooks and integrations
  • Allow requests to the local network from system hooks

第二步 Jenkins创建Job

首页 —> 新建Item —> name: auto

构建触发器

找到Build when a change is pushed to GitLab. GitLab webhook勾选然后下面找到高级点开

  • Secret token:生成GitLab webhook的Token

第三步 GitLab设置Webhook

点击要构建的项目进去 —> Settings —> Webhooks —> Add new webhook

  • URL:这个值在上一步GitLab webhook URL:后面的项目地址
  • Secret token:这是上一步在Jenkins申请的Token
  • Trigger:选择要自动构建的动作
    • Push events:Push动作
      • All branches:所有分支
      • Wildcard pattern:通配符模式
      • Regular expression:正则表达式
    • Tag push events:标签推送事件
    • Comments:评论
    • Confidential comments:机密评论
    • Issues events:问题事件
    • Confidential issues events:机密问题事件
    • Merge request events:合并请求事件
    • Job events:作业事件
    • Pipeline events:流水线事件
    • Wiki page events:维基页面事件
    • Deployment events:部署事件、
    • Feature flag events:功能标志事件
    • Releases events:发布事件
    • Emoji events:表情事件
    • Project or group access token events:项目或群组访问令牌事件

Jenkins-部署

war包部署

Jenkins 新版本的需要高版本的JDK支持

JDK安装

bash
tar -xvf jdk-17.0.10_linux-x64_bin.tar.gz -C /usr/local/jdk-17.0.10/

# 配置环境变量
cat >> /etc/profile << "EOF"
export JAVA_HOME=/usr/local/jdk-17.0.10
export JRE_HOME=${JAVA_HOME}/jre
export CLASSPATH=.:${JAVA_HOME}/lib:${JRE_HOME}/lib:$CLASSPATH
export JAVA_PATH=${JAVA_HOME}/bin:${JRE_HOME}/bin
export PATH=$PATH:${JAVA_PATH}
EOF

# 生效
source /etc/profile

启动 Jenkins

bash
wget http://mirrors.jenkins.io/war-stable/2.346.3/jenkins.war

# 启动
nohup java -jar jenkins.war > /var/log/jenkins.log 2>&1 &

创建Service管理文件

bash
# 工作目录
mkdir -p /data/jenkins

cat > /usr/lib/systemd/system/jenkins.service << "EOF"
[Unit]
Description=Jenkins Continuous Integration Server
Documentation=https://jenkins.io
After=network.target

[Service]
Type=simple
Environment="JENKINS_HOME=/data/jenkins"
Environment="JAVA_OPTS=-Djava.awt.headless=true -Xmx2048m -Xms512m"
ExecStart=/usr/local/jdk-17.0.10/bin/java $JAVA_OPTS -jar /opt/jenkins/jenkins.war
SuccessExitStatus=143
Restart=always
RestartSec=5
LimitNOFILE=8192
LimitNPROC=8192

[Install]
WantedBy=multi-user.target
EOF

systemctl daemon-reload
systemctl start jenkins

访问

jenkins 默认启动端口是8080

初始密码在/root/.jenkins/secrets/initialAdminPassword

bash
cat /root/.jenkins/secrets/initialAdminPassword

修改插件下载源

如果用java命令启动的情况下,工作目录就在当前的.jenkins,如果是yum安装的功能工作目录在/var/lib/jenkins/updates,这里工作目录以/data/jenkins为例

bash
# 替换所有插件下载的url
sed -i 's/https:\/\/updates.jenkins.io\/download/http:\/\/mirrors.tuna.tsinghua.edu.cn\/jenkins/g' /data/jenkins/updates/default.json

# 替换测试的url
sed -i 's/https:\/\/www.google.com/https:\/\/www.baidu.com/g' /data/jenkins/updates/default.json

systemctl restart jenkins

Docker部署

bash
# 创建挂载目录
mkdir -p /data/jenkins
chown -R 1000:1000 /data/jenkins
chmod 755 /data/jenkins

# 资源文件
cat > jenkins.yaml << 'EOF'
services:
  jenkins:
    container_name: jenkins
    image: jenkinsci/blueocean
    restart: always
    ports:
      - "49000:8080"
      - "50000:50000"
    volumes:
      - /data/jenkins:/var/jenkins_home
      - /var/run/docker.sock:/var/run/docker.sock
    environment:
      - TZ=Asia/Shanghai
    resources:
      limits:
        cpus: '1'        # 最多使用1个CPU核心
        memory: 1024M     # 最多使用1024M内存
      reservations:
        cpus: '0.25'     # 保证至少0.25个CPU核心
        memory: 128M     # 保证至少128MB内存
EOF

# 部署容器
docker compose -f jenkins.yaml up -d
# 查看初始密码
cat /data/jenkins/secrets/initialAdminPassword

Jenkins 安全设置

禁止用户自动注册

高版本的Jenkins默认是禁止的

Manager Jenkins —> Secuity —> Authentication

Jenkins 插件管理

插件说明

  • **Updates Plugins **:查看已安装插件的可用更新。
  • Available Plugins:浏览和安装 Jenkins 插件中心的所有插件。
  • **Installed Plugins **:查看和管理已安装的插件(可卸载或禁用)。
  • **Advanced Plugins **:手动上传 .hpi.jpi文件进行安装,或更换更新站点。

离线插件安装

清华大学地址:https://mirrors.tuna.tsinghua.edu.cn/jenkins/plugins

  • 下载相应的插件.hpi文件
  • 上传离线文件(单个文件):Manager Jenkins — > Plugins —> Advanced Plugins
  • 部署

Jenkins首次指纹

Jenkins首次连接远程服务器或Git仓库都需要指纹记录,可以提前记录指纹

bash
ssh-keyscan 192.168.148.110 >> /root/.ssh/known_hosts

Jenkins-多节点构建

Jenkins多节点是为了分担主节点压力,构建任务可以分配到从节点执行,构建过程中涉及到的软件指令需要再从节点安装

基础插件安装

日期同步

bash
dnf -y install ntpdate
# 日期同步
ntpdate ntp1.aliyun.com

安装git

bash
dnf -y install git

安装JDK

bash
wget https://download.java.net/java/GA/jdk22.0.1/c7ec1332f7bb44aeba2eb341ae18aca4/8/GPL/openjdk-22.0.1_linux-x64_bin.tar.gz
tar xvf openjdk-22.0.1_linux-x64_bin.tar.gz -C /usr/local/
 # 编辑环境变量配置文件
cat >> /etc/profile << "EOF"
export JAVA_HOME=/usr/local/jdk-22.0.1
export JRE_HOME=${JAVA_HOME}/jre
export CLASSPATH=.:${JAVA_HOME}/lib:${JRE_HOME}/lib:$CLASSPATH
export JAVA_PATH=${JAVA_HOME}/bin:${JRE_HOME}/bin
export PATH=$PATH:${JAVA_PATH}
EOF

source /etc/profile

# 检测
java -version

# 创建软连接否则主节点会找不到命令
ln -s /usr/local/jdk-22.0.1/bin/* /usr/bin/

创建密钥

这里创建的密钥是用于从节点拉取GitLab代码仓库的密钥和从节点连接远程服务器使用

bash
# 创建密钥
ssh-keygen -t rsa -b 4096 -f ~/.ssh/id_rsa -N '' -C "jenkins-slave-01@example.com"

# 查看公钥
cat ~/.ssh/id_rsa.pub

# 从节点到远程服务器免密
ssh-copy-id -i ~/.ssh/id_rsa root@192.168.148.240

创建主节点凭证

  1. 进入 Manage JenkinsManage Credentials
  2. 选择 SystemGlobal credentials (unrestricted)
  3. 点击 Add Credentials,按以下格式创建:

表单信息

  • Kind(类型):选择SSH Username with private key
  • Scope(范围):Global
  • ID(唯一标识):jenkins-server
  • Description(描述):Jenkins主密钥key
  • Username(key的账号):root
  • Private Key(id_rsa):粘贴id_rsa的私钥
  • Passphrase(密钥密码)

创建Jenkins节点服务器

首页 —> Manage Jenkins —> Nodes —> New Node

  • 节点名称:自定义如:jenkins-slave-01

  • Type:

    • Permanent Agent:首次添加只能选择这个
    • 复制现有节点:搜索之前创建节点
  • 远程工作目录:/data/jenkins需要在节点提前创建

  • 启动方式:Launch agents via SSH

    • 主机:从节点IP地址
    • Credentials:连接凭证选择上一步创建的Jenkins主密钥key
  • Tool Locations:工具位置列表

    • Git:/usr/bin/git只有Git才要设置完整的可执行文件路径

任务中使用

任务配置中找到限制项目的运行节点勾选,标签表达式搜索node节点的名。选择完成后需要将后面的空格删除点

构建后操作

Send build artifacts over SSH

在选择SSH Server远程服务器后点开高级然后勾选Credentials

  • Verbose output in console:在控制台输出详细日志,便于排查问题

  • Username:创建密钥时的用户,默认就是root

  • Passphrase / Password:密码

  • Path to key:密钥文件的路径/root/.ssh/id_rsa

  • Key:密钥id_rsa的内容,这里要选择从节点的密钥key

  • Exec in pty:必须勾选!解决进程卡住问题的关键选项

部署前端项目

Git

  • Repository URL:复制Gitlab代码仓库地址
  • Credentials:选择上一步创建的凭证
  • Branches to build:设置分支

构建环境

Provide Node & npm bin/ folder to PATH

这个需要提前配置NodeJS插件

Build Steps

这步是构建步骤,用于源代码构建打包操作

Execute shell

shell
# 例如前端
npm install
npm run build
tar zcf dist.tar.gz dist

构建后操作

Send build artifacts over SSH

这个是构建后SSH服务,用于发布操作

SSH Server

  • Name:Publish Over SSH插件添加远程服务
Transfer Set

传输配置。可以增加多个文件传输配置

  • Source files:要传输的源文件,支持通配符例如 **/*.zip

  • Remove prefix:在传输文件时,移除源文件路径中的指定前缀

    如果 Source filespackages/project/dist.tar.gz,而 Remove prefix填写 packages/project/,那么文件传输到远程服务器时,路径就会从 packages/project/dist.tar.gz变为 dist.tar.gz。您的配置中此项为空,意味着保持原路径结构。

  • Remote directory:远程目录。指定文件要被传输到远程服务器上的哪个目录,最终是以Publish Over SSH配置的路径为起始点

  • Exec command:文件成功传输到远程服务器之后,在远程服务器上执行的 Shell 命令。

    shell
    tar xf dist.tar.gz
    rm -rf /data/wwwroot/www
    mv dist /data/wwwroot/www

部署后端Java

部署Nexus部署私服

Nexus是Maven仓库管理器,也可以叫Maven的私服,是私服的一种。

Nexus的官网 :http://www.sonatype.com/

安装JDK

bash
wget https://download.java.net/java/GA/jdk22.0.1/c7ec1332f7bb44aeba2eb341ae18aca4/8/GPL/openjdk-22.0.1_linux-x64_bin.tar.gz
tar xvf openjdk-22.0.1_linux-x64_bin.tar.gz -C /usr/local/
# 编辑环境变量配置文件
cat >> /etc/profile << "EOF"
export JAVA_HOME=/usr/local/jdk-22.0.1
export JRE_HOME=${JAVA_HOME}/jre
export CLASSPATH=.:${JAVA_HOME}/lib:${JRE_HOME}/lib:$CLASSPATH
export JAVA_PATH=${JAVA_HOME}/bin:${JRE_HOME}/bin
export PATH=$PATH:${JAVA_PATH}
EOF

source /etc/profile
# 查看java版本
java -version

# 创建软连接
ln -s /usr/local/jdk-22.0.1/bin/* /usr/bin

安装Nexus

下载地址:https://www.sonatype.com/products/sonatype-nexus-oss-download

bash
tar -zxvf nexus-3.13.0-01-unix.tar.gz -C /usr/local

# 配置环境变量,添加NEXUS_HOME
cat >> /etc/profile << 'EOF'
export NEXUS_HOME=/usr/local/nexus-3.13.0-01
export PATH=$PATH:$NEXUS_HOME/bin
EOF
source /etc/profile

# 访问Web
http://ip:8081/

系统优化

bash
# 创建程序用户
useradd nexus -s /bin/bash
echo 'run_as_user="nexus"' > /usr/local/nexus-3.13.0-01/bin/nexus.rc
mkdir /usr/local/sonatype-work
chown nexus:nexus /usr/local/sonatype-work

# 设置句柄数
vim /etc/security/limits.conf
nexus - nofile 65536

创建service管理文件

bash
cat > /usr/lib/systemd/system/nexus.service << 'EOF'
[Unit]
Description=nexus service
After=network.target
 
[Service]
Type=forking
LimitNOFILE=65536
ExecStart=/usr/local/nexus-3.13.0-01/bin/nexus start
ExecStop=/usr/local/nexus-3.13.0-01/bin/nexus stop
User=nexus
Restart=on-abort
 
[Install]
WantedBy=multi-user.target
EOF

systemctl daemon-reload
systemctl enable nexus --now

管理命令

bash
# 启动
nexus start
# 状态
nexus status
# 重启
nexus restart
# 强制重新刷新仓库
nexus force-reload
# 关闭
nexus stop

配置Nexus

登录Nexus Web UI,管理员默认账户密码为admin/admin123

nexus 3.13 自带的部分仓库的说明:

  • maven-central:代理仓库,该仓库代理Maven中央仓库,策略为release,因此只会下载和缓存中央仓库中的发布版本的构件。
  • maven-releases: 宿主仓库,策略为release,用来部署组织内部的发布版本的构件。
  • maven-snapshots:宿主仓库,策略为snapshots,用来部署组织内部的快照版本的构件。
  • maven-public:仓库组,包含了以上3个仓库

设置阿里云加速

最上边有个齿轮的图标,然后在菜单栏中点击Repository—>Repositorys —>找到 maven-central—>找到Proxy

  • Remote storage:填写代理加速地址https://maven.aliyun.com/nexus/content/groups/public/

然后返回Repositorys点击maven-releases找到URL这是私有Nexus地址

配置Maven

进入到Maven安装目录然后打开settings.xml

bash
# 在servers模块下添加认证信息
<server>
  <id>my-nexus-releases</id>
  <username>admin</username>
  <password>admin123</password>
</server>
<server>
  <id>my-nexus-snapshots</id>
  <username>admin</username>
  <password>admin123</password>
</server>

# 在mirror模块告诉私服地址
<mirror>
  <id>nexus</id>
  <mirrorOf>*</mirrorOf>
  <url>http://192.168.148.114:8081/repository/maven-public/</url>
</mirror>

# 在profiles模块下添加profile配置
<profile>
  <id>nexus</id>
  <repositories>
    <repository>
      <id>nexus</id>
      <url>http://192.168.148.114:8081/repository/maven-public/</url>
      <releases><enabled>true</enabled></releases>
      <snapshots> <enabled>true</enabled></snapshots>
    </repository>
  </repositories>
  <pluginRepositories>
    <pluginRepository>
      <id>nexus</id>
      <url>http://192.168.148.114:8081/repository/maven-public/</url>
      <releases><enabled>true</enabled></releases>
      <snapshots><enabled>true</enabled></snapshots>
    </pluginRepository>
  </pluginRepositories>
</profile>

# 激活仓库
<activeProfiles>
  <activeProfile>nexus</activeProfile>
</activeProfiles>

构建环境

自定义变量

【构建环境】找到Inject environment variables to the build process將環境變量注入構建過程

  • Properties Content屬性內容:自定义变量

    bash
    DEVOPS_MYSQL_HOST=192.168.148.171
    DEVOPS_MYSQL_PORT=3306
    DEVOPS_MYSQL_DATABASE_NAME=gunsdb
    DEVOPS_MYSQL_USERNAME=root
    DEVOPS_MYSQL_PASSWORD=123456

Build Steps

Execute shell

这里可以执行shell指令

Invoke top-level Maven targets

调用mvn指令

  • Maven 版本:这里选择之前配置的Maven插件
  • 目标:mvn执行的具体指令。Jenkins执行时已自动包含mvn命令,所以这里不需要输如mvn直接输入具体指令如:clean package -DskipTests
bash
mvn clean package -Dspring.profiles.active=prod
  • -Dspring.profiles.active=prod会激活 application-prod.yml配置,覆盖默认的 application.yml

构建后操作

Send build artifacts over SSH

这个是构建后SSH服务,用于发布操作

SSH Server

  • Name:Publish Over SSH插件添加远程服务
Transfer Set

传输配置。可以增加多个文件传输配置

  • Source files:要传输的源文件,支持通配符例如 **/*.jar

  • Remove prefix:在传输文件时,移除源文件路径中的指定前缀

    如果 Source filestarget/guns.jar,而 Remove prefix填写 target/,那么文件传输到远程服务器时,路径就会从 target/guns.jar变为 guns.jar。您的配置中此项为空,意味着保持原路径结构。

  • Remote directory:远程目录。指定文件要被传输到远程服务器上的哪个目录,最终是以Publish Over SSH配置的路径为起始点

  • Exec command:文件成功传输到远程服务器之后,在远程服务器上执行的 Shell 命令。

    bash
    java -jar guns.jar --spring.profiles.active=prod
    
    # 启动时指定环境变量
    java -jar guns.jar \
      --spring.profiles.active=prod \
      --DEVOPS_MYSQL_HOST=192.168.148.171 \
      --DEVOPS_MYSQL_PORT=3306 \
      --DEVOPS_MYSQL_DATABASE_NAME=gunsdb \
      --DEVOPS_MYSQL_USERNAME=root \
      --DEVOPS_MYSQL_PASSWORD=123456

经典案例

部署前端SoybeanAdmin

SoybeanAdmin是一个清新优雅、高颜值且功能强大的后台管理模板,基于最新的前端技术栈,包括 Vue3, Vite6, TypeScript, Pinia 和 UnoCSS。它内置了丰富的主题配置和组件,代码规范严谨,实现了自动化的文件路由系统。此外,它还采用了基于 ApiFox 的在线Mock数据方案。SoybeanAdmin 为您提供了一站式的后台管理解决方案,无需额外配置,开箱即用。同样是一个快速学习前沿技术的最佳实践。

Gitee:https://gitee.com/honghuangdc/soybean-admin-element-plus

环境准备

主机IP用途操作系统预装软件
jenkins-server192.168.148.111jenkins主分配构建任务openEuler-24.03Jenkins
jenkins-slave-01192.168.148.112jenkins从节点,执行构建任务openEuler-24.03Git、NodeJs
web192.168.148.113构建后的HTML静态页服务openEuler-24.03Nginx

NodeJs:Node Js 16+。下载地址:https://nodejs.org/zh-cn/download/

创建密钥

在jenkins-server、jenkins-slave-01

bash
# 创建密钥
ssh-keygen -t rsa -b 4096 -f ~/.ssh/id_rsa -N '' -C "jenkins@example.com"

# 查看公钥
cat ~/.ssh/id_rsa.pub

# 免密登录(同时可以生成指纹,以免主从节点无法正常通信)
ssh-copy-id -i ~/.ssh/id_rsa root@IP

部署前端

bash
dnf -y install nginx
# 启动服务
nginx

部署Jenkins

安装Jenkins

在jenkins-server操作

参考[Jenkins-基础 —> Jenkins 安装]

安装Nodes节点

在jenkins-slave-01和jenkins-slave-02操作

加入集群

参考[Jenkins-多节点构建]

安装NodeJs
bash
wget https://nodejs.org/dist/latest-v22.x/node-v22.18.0-linux-x64.tar.gz

tar xvf node-v22.18.0-linux-x64.tar.gz
mv node-v22.18.0-linux-x64 /usr/local/nodejs
# 创建软连接
ln -s /usr/local/nodejs/bin/node /usr/local/bin/node
ln -s /usr/local/nodejs/bin/npm /usr/local/bin/npm

# 安装cnpm与配置淘宝镜像
npm config set registry https://registry.npmmirror.com/
# 查看版本
node --version
npm --version

# 安装插件临时使用加速
npm install -g yarn --registry https://registry.npmmirror.com

添加远程主机

首页 —> Manager Jenkins —> System —> SSH Servers

  • Name:web
  • Hostname:192.168.148.113
  • Username:root
  • Remote Directory:/tmp/

Jenkins创建构建任务

General

找到限制项目的运行节点勾选,标签表达式搜索节点名如:jenkins-slave

源码管理

Git:设置代码仓库地址

构建环境

找到Provide Node & npm bin/ folder to PATH并且勾选

  • NodeJS Installation:选择插件
  • npmrc file:选择设置的Managed files加速配置

Build Steps

Execute shell
shell
export NODE_OPTIONS="--max-old-space-size=4096"
npm install -g pnpm
pnpm install
pnpm build
tar zcf dist.tar.gz dist

构建后操作

选择Send build artifacts over SSH远程同步

  • Name:选择web

  • Transfers

    • Source files:dist.tar.gz

    • Exec command:

      shell
      tar xf /tmp/dist.tar.gz -C /tmp/
      rm -rf /data/wwwroot/www
      mv /tmp/dist /data/wwwroot/www
      # rm -rf /tmp/dist.tar.gz

Java前后端分离项目部署

此案例选择的是码云上的guns开源项目,版本选择是的是Guns v8.3.0,前后端分离版本,后端基于主流技术Spring Boot3,数据库是MySQL

Gitee:https://gitee.com/stylefeng/guns

官网:https://www.javaguns.com/

环境准备

主机IP用途操作系统预装软件
jenkins-server192.168.148.111jenkins主分配构建任务openEuler-24.03Jenkins
jenkins-slave-01192.168.148.112jenkins从节点,执行构建任务openEuler-24.03Git、JDK、NodeJs、Maven
jenkins-slave-02192.168.148.113jenkins从节点,执行构建任务openEuler-24.03Git、JDK、NodeJs、Maven
guns-frontend192.168.148.114部署前端代码openEuler-24.03Nginx
guns-backend192.168.148.115部署后端代码openEuler-24.03JDK
mysql192.168.148.116部署MySQL数据库openEuler-24.03MySQL

创建密钥

在jenkins-server、jenkins-slave-01、jenkins-slave-02执行

bash
# 创建密钥
ssh-keygen -t rsa -b 4096 -f ~/.ssh/id_rsa -N '' -C "jenkins@example.com"

# 查看公钥
cat ~/.ssh/id_rsa.pub

# 免密登录(同时可以生成指纹,以免主从节点无法正常通信)
ssh-copy-id -i ~/.ssh/id_rsa root@IP

部署业务服务

部署前端

在guns-frontend操作

安装软件
bash
dnf -y install nginx
Nginx配置
bash
cat > /etc/nginx/conf.d/guns-frontend.conf << 'EOF'
server {
    listen 8080;
    server_name localhost;

    location / {
        root /data/wwwroot/www/guns-front-project/;
        index index.html;
        try_files $uri $uri/ /index.html;
    }
    location /api/ {
        proxy_pass http://192.168.148.115:8080/;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
    }
}
EOF

# 重新加载配置
nginx -s reload

部署后端

安装软件
bash
# 下载JDK
wget https://download.java.net/java/GA/jdk22.0.1/c7ec1332f7bb44aeba2eb341ae18aca4/8/GPL/openjdk-22.0.1_linux-x64_bin.tar.gz
tar xvf openjdk-22.0.1_linux-x64_bin.tar.gz -C /usr/local/

# 设置环境变量
cat >> /etc/profile << "EOF"
export JAVA_HOME=/usr/local/jdk-22.0.1
export JRE_HOME=${JAVA_HOME}/jre
export CLASSPATH=.:${JAVA_HOME}/lib:${JRE_HOME}/lib:$CLASSPATH
export JAVA_PATH=${JAVA_HOME}/bin:${JRE_HOME}/bin
export PATH=$PATH:${JAVA_PATH}
EOF

# 配置生效
source /etc/profile

# 查看版本
java -version

部署MySQL

bash
dnf -y install mysql

mysql -uroot -p'' -e "create database gunsdb"

部署Jenkins

安装Jenkins

在jenkins-server操作

参考Jenkins基础 —> Jenkins 安装

安装Nodes节点

在jenkins-slave-01和jenkins-slave-02操作

加入集群

参考Jenkins 多节点构建

安装NodeJs
bash
wget https://nodejs.org/dist/latest-v22.x/node-v22.18.0-linux-x64.tar.gz

tar xvf node-v22.18.0-linux-x64.tar.gz
mv node-v22.18.0-linux-x64 /usr/local/nodejs
# 创建软连接
ln -s /usr/local/nodejs/bin/node /usr/local/bin/node
ln -s /usr/local/nodejs/bin/npm /usr/local/bin/npm

# 安装cnpm与配置淘宝镜像
npm config set registry https://registry.npmmirror.com/
# 查看版本
node --version
npm --version

# 安装插件临时使用加速
npm install -g yarn --registry https://registry.npmmirror.com
安装Maven
bash
# 下载
wget https://mirrors.tuna.tsinghua.edu.cn/apache/maven/maven-3/3.8.9/binaries/apache-maven-3.8.9-bin.tar.gz
tar -zvxf apache-maven-3.8.9-bin.tar.gz -C /usr/local

# 环境变量
cat >> /etc/profile << "EOF"
export M2_HOME=/usr/local/apache-maven-3.8.9
export PATH=$M2_HOME/bin:$PATH
EOF
source /etc/profile

# 验证
mvn -v

# 创建包存储目录
mkdir -p /data/maven-repository
# 切换国内源,进入到maven的conf目录中,配置文件中
vim /usr/local/apache-maven-3.8.9/conf/settings.xml
# 配置本地仓库,下载的包存在该目录
<localRepository>/data/maven-repository</localRepository>
# 配置阿里云的镜像地址
# 在 <mirrors> 标签下添加
<mirror>
  <id>alimaven</id>
  <name>aliyun maven</name>
  <mirrorOf>central</mirrorOf>
  <url>http://maven.aliyun.com/nexus/content/groups/public/</url>
</mirror>

Jenkins插件

在Jenkins可视化界面操作

Nodejs插件:参考[常用插件配置 —> Node.js]

Maven插件:参考[常用插件配置 —> Maven]

添加远程主机

首页 —> Manager Jenkins —> System —> SSH Servers

  • Name:guns-frontend/guns-backend
  • Hostname:192.168.148.114/192.168.148.115
  • Username:root
  • Remote Directory:/tmp/

Jenkins创建构建任务

General

找到限制项目的运行节点勾选,标签表达式搜索节点名如:jenkins-slave

源码管理

Git:设置代码仓库地址

构建环境

找到Provide Node & npm bin/ folder to PATH并且勾选

  • NodeJS Installation:选择插件
  • npmrc file:选择设置的Managed files加速配置

Build Steps

Execute shell
shell
cd guns-front-project
npm install
npm run build
tar zcf dist.tar.gz dist
Invoke top-level Maven targets
  • Maven 版本:选择设置的插件名

  • 目标:这里只需要设置mvn后面的指令即可,mvn关键字执行时默认携带

    bash
    clean package -Dspring.profiles.active=prod

构建后操作

部署前端

选择Send build artifacts over SSH远程同步

  • Name:选择guns-frontend

  • Transfers

    • Source files:guns-front-project/dist.tar.gz

    • Exec command:

      shell
      tar xf /tmp/guns-front-project/dist.tar.gz -C /tmp/guns-front-project/
      [ -d /data/wwwroot/www/guns-front-project/ ] || mkdir -p /data/wwwroot/www/guns-front-project/
      rm -rf /data/wwwroot/www/guns-front-project/*
      mv /tmp/guns-front-project/dist /data/wwwroot/www/guns-front-project/
      rm -rf /tmp/guns-front-project/dist.tar.gz
部署后端

选择Send build artifacts over SSH远程同步

  • Name:选择guns-backend

  • Transfers

    • Source files:target/guns.jar

    • Exec command:

      shell
      [ -d /data/wwwroot/www/ ] || mkdir -p /data/wwwroot/www/
      rm -rf /data/wwwroot/www/guns.jar
      mv /tmp/target/guns.jar /data/wwwroot/www/
      cd /data/wwwroot/www/
      BUILD_ID=dontKillMe sh startJava.sh start

    startJava.sh:

    bash
    #!/bin/bash
    # export JAVA_HOME=/usr/java/jdk1.8.0_131
    # export JRE_HOME=/$JAVA_HOME/jre
    # export CLASSPATH=.:$JAVA_HOME/jre/lib/rt.jar:$JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar
    # export PATH=$PATH:$JAVA_HOME/bin:$JRE_HOME/bin
    
    export PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin
    
    # 这里可替换为你自己的执行程序,其他代码无需更改
    APP_NAME='guns.jar'
    # 日志目录
    LOG_PATH='./logs/'
    
    # 使用说明,用来提示输入参数
    usage() {
        echo "Usage: sh robotcenter.sh [start|stop|restart|status]"
        exit 1
    }
    
    # 检查程序是否在运行
    is_exist(){
        pid=`ps -ef|grep $APP_NAME|grep -v grep|awk '{print $2}'`
        #如果不存在返回1,存在返回0     
        if [ -z "${pid}" ]; then
            return 1
        else
            return 0
        fi
    }
    
    # 启动方法
    start(){
        is_exist
        if [ $? -eq 0 ]; then
            echo "${APP_NAME} is already running. pid=${pid}"
        else
            if [ ! -d ${LOG_PATH} ];then
                mkdir ${LOG_PATH}
            fi
            nohup java -jar -Xms512m -Xmx512m ${APP_NAME} --spring.profiles.active=prod \
    	       --DEVOPS_MYSQL_HOST=192.168.148.171 \
          	       --DEVOPS_MYSQL_PORT=3306 \
                   --DEVOPS_MYSQL_DATABASE_NAME=gunsdb \
                   --DEVOPS_MYSQL_USERNAME=root \
                   --DEVOPS_MYSQL_PASSWORD=123456 >> ${LOG_PATH}${APP_NAME}-$(date "+%Y-%m-%d").log 2>&1 &
            sleep 1
            is_exist
            if [ $? -eq 0 ]; then
                echo "${APP_NAME} is already running. pid=${pid}"
            else 
                echo "${APP_NAME} is not running";
            fi
        fi
    }
    
    # 停止方法
    stop(){
        is_exist
        if [ $? -eq "0" ]; then
            kill -9 $pid
        else
            echo "${APP_NAME} is not running"
        fi  
    }
    
    # 输出运行状态
    status(){
        is_exist
        if [ $? -eq "0" ]; then
            echo "${APP_NAME} is running. Pid is ${pid}"
        else
            echo "${APP_NAME} is NOT running."
        fi
    }
    
    # 重启
    restart(){
        stop
        sleep 5
        start
    }
    
    # 根据输入参数,选择执行对应方法,不输入则执行使用说明
    case "$1" in
      "start")
        start
        ;;
      "stop")
        stop
        ;;
      "status")
        status
        ;;
      "restart")
        restart
        ;;
      *)
        usage
        ;;
    esac

K8s插件拉取Harbor构建

mermaid
flowchart TD
    subgraph Dev [开发域]
        A[开发者] -->|提交代码、打标签| B[GitLab]
    end

    subgraph CICD [CI/CD域]
        B -->|WebHook 触发| C[Jenkins<br>独立部署]
        C -->|调用| D[构建代理]
        D -->|执行流水线| E[构建 & 打包镜像]
        E -->|推送镜像| F[Harbor<br>独立部署]
    end

    subgraph K8s [Kubernetes域]
        G[K8s Node<br>已配置Harbor证书]
        H[K8s Node<br>已配置Harbor证书]
        I[K8s API Server]
    end

    F -->|1. 镜像存储| F
    C -->|2. 部署指令| I
    I -->|3. 调度Pod| G
    G -->|4. 拉取镜像| F
    H -->|4. 拉取镜像| F

    C -->|读取配置| J[Kubeconfig<br>认证文件]
    C -->|使用账户| K[ServiceAccount<br>harbor-ci]

用法详解

  • 概述
  • 使用标签
  • Pipeline 支持
  • 多容器支持
  • 配置 pod 模板
  • 配置容器模板
  • 指定代理默认连接超时时间
  • 使用 yaml 定义 Pod Templates
  • Liveness Probe Usage 活性探针的使用

Jenkins 安装 Kubernetes插件

插件介绍

Jenkins 的 Kubernetes 插件可以实现在 Kubernetes 集群中运行动态的 Agent, 并在动态 Agent 中去构建任务或运行 Pipeline 代码。

该插件为每个启动的代理创建一个 Kubernetes Pod,并在每次构建后停止它。

代理会使用 JNLP(inbound agents)启动,因此 agents 会自动连接到 Jenkins 控制器(master)。为此,会自动注入一些环境变量:

  • JENKINS_URL : Jenkins 网页界面网址
  • JENKINS_SECRET : 认证的秘钥
  • JENKINS_AGENT_NAME : Jenkins 代理的名字
  • JENKINS_NAME :Jenkins 代理的名称(已弃用。仅用于向后兼容)

安装

Manager Jenkins —> Plugins —> Available plugins —> 搜索Kubernetes

插件包括KubernetesKubernetes Client APIKubernetes CredentialsKubernetes CLI

配置

填写Kubernetes插件配置。为此,您将打开 Jenkins UI 并导航到:

Manage Jenkins —> Clouds —> New Cloud

  • Cloud name:自定义如:Kubernetes
  • Type:勾选Kubernetes

这里分两种情况

  1. jenkins 部署在 kubernetes 集群内部
  2. jenkins 部署在 kubernetes 集群外部
Jenkins 运行于 Kubernets 内部的情况下
  • Kubernetes 地址:不需要填写
  • Kubernetes 服务证书 key:不需要填写
  • Kubernetes 命名空间:命名空间按照自己创建的Jenkins pod填写
配置 Jenkins URL 和 通道
bash
# 查看Jenkins地址
kubectl -n jenkins get service
  • Jenkins 地址:http://jenkins:8080
  • Jenkins 通道:jenkins:50000
Jenkins 在 Kubernetes 集群的外部

在Kubernetes外部运行Jenkins控制器时,需要将凭证设置为secret text。凭证的值将是您在代理将运行的集群中为Jenkins创建的服务帐户的令牌。

支持的认证方式如下:

  • Secret File (kubeconfig file)
  • Secret text (Token-based authentication) (OpenShift)
  • Google Service Account from private key (GKE authentication)

我们的 Kubernetes 集群就是用 Secret File 方式即可。 这个方式需要在你访问 Jenskins UI 的浏览器所在的主机上保存一份访问 Kubernetes 集群的配置文件,就是我们平常使用 ~/.kube/config 文件就行。或者单独给你的 Jenkins 创建有权限访问和控制(创建、更新、删除)集群资源的账户及其授权信息。

配置连接凭证
bash
# 将内容导出到本地方便后续上传,可以保存名为k8s.conf
cat ~/.kube/config

Manager jenkins —> Credentials —> 全局

  • 类型:选择Secret file
  • 范围:选择Global
  • File:上传k8s.conf
  • ID:唯一表示如:k8s.conf
  • 描述:Kubernetes配置
配置 Jenkins 和 jenkins 代理之间的连接信息

代理和控制端的连接是使用 TCP 协议通信的,需要控制端打开 50000 端口。 打开方式如下:

Manage Jenkins —> Security —> TCP port for inbound agents

  • 指定端口:50000
配置 kubernetes 集群URL和名称空间
  • Kubernetes 地址:https://192.168.148.180:6443
  • Kubernetes 命名空间:jenkins
  • 凭据:选择上一步配置的k8s.conf
  • 连接测试:出现Connected to Kubernetes v1.31.4为成功
配置Jenkins地址
  • Jenkins 地址:http://jenkins:8080
  • Jenkins 通道:jenkins:50000
  • 默认提供的模板名称:jenkins-template指定pod模板的名称

我测试的时候可能因为pod无法请求jenkins:5000地址后来在kubernetes启动了一个svc并负载了jenkins实际地址

bash
cat > jenkins-svc.yaml << 'EOF'
apiVersion: v1
kind: Service
metadata:
  name: jenkins-external-svc
  namespace: jenkins # 建议与Agent Pod命名空间一致
spec:
  type: ClusterIP
  ports:
  - port: 8080
    targetPort: 8080
    name: http
  - port: 50000
    targetPort: 50000
    name: agent
---
apiVersion: v1
kind: Endpoints
metadata:
  name: jenkins-external-svc
  namespace: default
subsets:
- addresses:
  - ip: 192.168.148.111 # 【替换】为您Jenkins服务器的真实IP
  ports:
  - port: 8080
    name: http
  - port: 50000
    name: agent
EOF

kubectl apply -f jenkins-svc.yaml

# Jenkins 通道修改为:
jenkins-external-svc.default.svc.cluster.local:50000
配置 Pod 模板

除了需要配置连接到 Kubernetes 集群的信息外,还需要在 Kubernetes Pod Template 部分,我们需要配置 Jenkins 代理的镜像 ,将用于启动 Pod。

Jenkins 默认情况下提供了一个镜像用于启动 Jenkins 代理,这个镜像不要覆盖,镜像中已经集成了 JDK 环境。假如还需要其他环境用于构建你的项目,可以向 Pod 模板中继续添加其他的镜像。也就是说一个模板中可以配置多个镜像。

Manage Jenkins —> Clouds —> 配置的节点如Kubernetes —> Pod Template —> Add a pod template

  • 名称:自定义如:jenkins-template
  • 命名空间:和上一步设置的命名空间保持一致jenkins
  • 标签列表:jenkinspod这里的标签很重要,希望使用这个模板作为Jenkins任务的时候需要这个名字
  • 容器列表:
    • 名称:inbound-agent
    • Docker 镜像:jenkins/inbound-agent:4.3-4
    • 工作目录:默认/home/jenkins/agent
    • 分配伪终端:勾选

创建Item任务

General

  • 名称:k8sdemo
  • 找到限制项目的运行节点并勾选
    • 标签表达式:搜索jenkinspod选择模板的标签
  • Build Steps:
    • Execute shell: