1. 背景
目前使用的Jenkins 版本2.289.3 很旧了,运行在Cenos6上。本次升级操作系统,升级新版Jenkins 2.528.3 LTS。为启用"参数化构建"功能,支持自由风格使用tag发版做准备。
2. 参考
3. 环境
- 操作系统 Ubuntu24.04
- 主服务器配置 VM 16C/64G/800G
- Jenkins版本 2.528.3 LTS
- Java版本 JDK21
4. 操作系统安装
略
5. Jenkins升级
5.1 整理当前Jenkins工作路径
- Jenkins安装目录和所有程序目录
bash
tree -d -L 1 /public/
/public/
├── ant
├── apache-maven-3.3.9
├── apache-maven-3.9.12
├── apache-maven-3.9.9
├── application
├── gradle-6.3-bin
├── java
├── jenkins
├── repository
├── software
└── spark-1.6.1
- jenkins目录是程序主目录。为了保持备份脚本目录统一(每天定时rsync备份),在其中定义了两个子目录
- jenkins-war -> /usr/lib/jenkins/ 链接指向真实程序目录
- root.jenkins -> /root/.jenkins/ 链接指向工作空间目录
- Jenkins工作空间目录(每天定时rsync备份)
bash
tree -a -d -L 1 /root/ | grep jenkins
├── .jenkins
5.2 同步所有文件到新服务器
bash
rsync -avz /public/ root@192.168.7.132:/public
rsync -avz /root/.jenkins root@192.168.7.132:/root/
rsync -avz /usr/lib/jenkins root@192.168.7.132:/usr/lib
5.3 同步Java环境到新服务器
- 本次升级使用jdk21
bash
# 新增加的jdk17和jdk21
rsync -avz /usr/local/jvm root@192.168.7.132: /usr/local/
# 保持旧jdk1.8不变,防止jenkins中有项目使用绝对路径
rsync -avz /usr/java root@192.168.7.132: /usr/
5.4 安装新版Jenkins
- 备份旧版Jenkins
bash
cd /usr/lib/jenkins && mv jenkins.war jenkins.war.20251223
- 下载最新Stable (LTS)
官网下载地址
bash
root@ubuntu24-192-168-007-132:/usr/lib/jenkins# sha256sum /usr/lib/jenkins/jenkins.war
bfa31f1e3aacebb5bce3d5076c73df97bf0c0567eeb8d8738f54f6bac48abd74 /usr/lib/jenkins/jenkins.warjenkins.war
5.5 启动新版Jenkins
- 使用java21,启动新版Jenkins 2.528.3
bash
/usr/local/jvm/java21/bin/java -jar /usr/lib/jenkins/jenkins.war --httpPort=8899 > jenkins.log 2>&1 &
5.6 解决启动插件错误
- 启动失败,报以下错误
- 原因是Matrix Authorization Strategy Plugin需要更新的Folders Plugin版本
bash
Plugin v3.2.8 (matrix-auth)
java.io.IOException: Failed to load: Matrix Authorization Strategy Plugin (matrix-auth 3.2.8)
[LF]> - Update required: Folders Plugin (cloudbees-folder 6.15) to be updated to 6.1026.ve06dfa_cf31c3 or higher
- 更新Folder插件
官方插件下载地址
- 进入插件目录
bash
cd /root/.jenkins/plugins
- 备份旧cloudbees-folder
bash
mv cloudbees-folder cloudbees-folder.old
mv cloudbees-folder.jpi cloudbees-folder.jpi.old
- 下载新cloudbees-folder.hpi并创建子目录
bash
ll | grep -i cloudbees-folder
# 新下载插件和新创建的子目录
drwxr-xr-x 5 root root 70 12月 17 18:41 cloudbees-folder/
-rw-r--r-- 1 root root 243117 12月 17 18:24 cloudbees-folder.hpi
# 旧备份文件
-rw-r--r-- 1 root root 223145 5月 12 2021 cloudbees-folder.jpi.old
drwxr-xr-x 5 root root 70 12月 15 01:32 cloudbees-folder.old/
5.7 新版Jenkins启动成功
http://192.168.7.132:8899/login?from=%2F

5.8 升级Jenkins所有插件
- 更换国内镜像源
- 华为源:https://mirrors.huaweicloud.com/jenkins/updates/update-center.json
- Jenkins-->ManageJenkins-->Plugins-->Advanced settings下配置

- 确保Jenkins-->ManageJenkins-->Plugins-->Updates 下再没有需要升级的插件

5.9 配置"抛弃旧构建"
- 旧版Jenkins升级后,需要单独配置抛弃旧构建(Discard old builds)
- 所有每个项目都重新配置(建议与下列修改built-in配置一并完成)

- 保持构建的天数 与 保持构建的最大个数是"或"关系
- 发布包保留天数 与 发布包保留最大个数也是"或"关系
- 为了节省空间,上述定义保留了10次构建记录 和 1个构建发布包
注意 :Jenkins升级成功后,如果不配置"抛弃旧构建(Discard old builds)",Jenkins会自动启动构建,生成并保留所有发布包,很容易撑满磁盘空间。
5.10 消除主节点术语变更警告
- Jenkins-->ManageJenkins下出现以下警告信息
html
The word "master" is being retired as the term for the main Jenkins process and the built-in node. The main process is now called "controller" and the built-in node is called just "built-in node". The UI has been updated with these changes. The following features are also affected:
The implicit label of the built-in node changes from master to built-in.
The built-in node's NODE_NAME environment variable also changes from master to built-in.
These changes could affect build behavior, so are not applied automatically. Before you apply these changes, you should do the following:
Review label assignments in job configurations and tool installers for uses of master label. Any such label assignments will not match the built-in node after migration. Besides updating these assignments, you could also explicitly add the master label to the built-in node.
Review use of the NODE_NAME environment variable in build scripts.
- 新版Jenkins启用"built-in"替代之前的"master"节点标签
- 这个变更不是必须的操作,如果不修改(Jenkins-->Manage Jenkins-->Nodes),之前每个项目配置的"master"节点仍然生效,如果修改(Jenkins-->Manage Jenkins-->Nodes),那么每个项目就必须重新配置,使用"built-in"替代之前的"master"。


5.11 消除基于角色的权限策略配置警告
- Jenkins-->ManageJenkins下出现以下警告信息
html
There are several permissions declared in Role Based Strategy plugin configuration, that are ambiguous. Classify them correctly with 'USER:username' or 'GROUP:groupname'.
- 新版Jenkins必须明确权限是组或用户,不允许旧版中模糊定义
- 通过web管理界面定义权限绑定组或用户功能不成功(页面刷新后仍然定义模糊)
- 因此只能通过修改config.xml文件方式定义
- 备份配置文件
bash
cp -rf /root/.jenkins/config.xml /root/.jenkins/config.bak
- 修改type="EITHER" 为准确组(group)或用户(user),举例如下:
bash
vim config.xml
bash
# 修改前原始记录
<assignedSIDs>
<sid type="EITHER">shijin</sid>
</assignedSIDs>
bash
# 修改后记录,绑定到用户上
<assignedSIDs>
<sid type="USER">shijin</sid>
</assignedSIDs>
注意: 需要停服修改对应记录,重启服务后才生效
5.12 消除SSL证书已过期警告
- Jenkins-->ManageJenkins-->Plugins下出现以下警告信息
html
There were errors checking the update sites: Signature verification failed in update site 'default' </div><div><a href='#' class='showDetails'>(显示详情)</a><pre style='display:none'>java.security.cert.CertificateExpiredException: NotAfter: Tue Jun 14 18:42:00 CST 2022<br> at java.base/sun.security.x509.CertificateValidity.valid(CertificateValidity.java:182)<br> at java.base/sun.security.x509.X509CertImpl.checkValidity(X509CertImpl.java:534)<br> at java.base/sun.security.provider.certpath.BasicChecker.verifyValidity(BasicChecker.java:190)<br> at java.base/sun.security.provider.certpath.BasicChecker.check(BasicChecker.java:144)<br> at java.base/sun.security.provider.certpath.PKIXMasterCertPathValidator.validate(PKIXMasterCertPathValidator.java:125)<br>Caused: java.security.cert.CertPathValidatorException: validity check failed<br> at java.base/sun.security.provider.certpath.PKIXMasterCertPathValidator.validate(PKIXMasterCertPathValidator.java:135)<br> at java.base/sun.security.provider.certpath.PKIXCertPathValidator.validate(PKIXCertPathValidator.java:224)<br> at java.base/sun.security.provider.certpath.PKIXCertPathValidator.validate(PKIXCertPathValidator.java:144)<br> at java.base/sun.security.provider.certpath.PKIXCertPathValidator.engineValidate(PKIXCertPathValidator.java:83)<br> at java.base/java.security.cert.CertPathValidator.validate(CertPathValidator.java:309)<br> at org.jvnet.hudson.crypto.CertificateUtil.validatePath(CertificateUtil.java:93)<br> at jenkins.util.JSONSignatureValidator.verifySignature(JSONSignatureValidator.java:88)<br> at hudson.model.UpdateSite.verifySignatureInternal(UpdateSite.java:297)<br> at hudson.model.UpdateSite.updateData(UpdateSite.java:260)<br> at hudson.model.UpdateSite.updateDirectlyNow(UpdateSite.java:240)<br> at hudson.model.UpdateSite.updateDirectlyNow(UpdateSite.java:235)<br> at hudson.PluginManager.checkUpdatesServer(PluginManager.java:2177)<br> at hudson.util.Retrier.start(Retrier.java:62)<br> at hudson.PluginManager.doCheckUpdatesServer(PluginManager.java:2148)<br> at jenkins.DailyCheck.execute(DailyCheck.java:93)<br> at hudson.model.AsyncPeriodicWork.lambda$doRun$0(AsyncPeriodicWork.java:110)<br> at java.base/java.lang.Thread.run(Thread.java:1583)<br></pre>
- 新版Jenkin提示证书过期,通过启动命令增加禁用签名检查参数消除
bash
/usr/local/jvm/java21/bin/java -Dhudson.model.DownloadService.noSignatureCheck=true -jar jenkins.war --httpPort=8899 > jenkins.log 2>&1 &
注意: 需要停服修改对应记录,重启服务后才生效
5.13 设置Jenkins语言
-
确保操作系统安装中文语言包并正确设置时区
-
Jenkins-->ManageJenkins-->Plugins-->Available Plugins 下安装Localization: Chinese (Simplified) 或 Localization Support Plugin

-
Jenkins-->ManageJenkins-->Appearance 设置中文

- 选中 Ignore browser preference and force this language to all users
- 选中 Allow all users to use their own language preference
5.14 设置Jenkins时区
- 通过启动命令增加时区参数设置
bash
/usr/local/jvm/java21/bin/java --Duser.timezone=Asia/Shanghai -jar jenkins.war --httpPort=8899 > jenkins.log 2>&1 &
5.15 配置Jenkins启动脚本
bash
vim /public/jenkins/restart.sh
bash
#!/bin/bash
JENKINS_WAR="/usr/lib/jenkins/jenkins.war"
PORT="8899"
LOG="/public/jenkins/jenkins.log"
# 64GB内存优化配置
JAVA_OPTS="-Xmx32g -Xms16g -XX:MaxMetaspaceSize=1g -XX:ReservedCodeCacheSize=512m"
JAVA_OPTS="$JAVA_OPTS -XX:+UseG1GC -XX:MaxGCPauseMillis=200 -XX:G1HeapRegionSize=8m"
JAVA_OPTS="$JAVA_OPTS -XX:InitiatingHeapOccupancyPercent=35 -XX:+ExplicitGCInvokesConcurrent"
JAVA_OPTS="$JAVA_OPTS -Dfile.encoding=UTF-8 -Dhudson.DNSMultiCast.disabled=true"
# 设置时区
JAVA_OPTS="$JAVA_OPTS -Duser.timezone=Asia/Shanghai"
# 关闭签名检查
JAVA_OPTS="$JAVA_OPTS -Dhudson.model.DownloadService.noSignatureCheck=true"
# 停止命令
PID=`ps -ef | grep '/usr/lib/jenkins/jenkins.war' |grep -v grep |awk '{print $2}'`
if [ -n "$PID" ]; then
echo -e "\n停止jenkins进程,PID: ${PID}"
kill -TERM "$PID" 2>/dev/null
sleep 3
# 等待优雅停止,最多15秒
for i in {1..5}; do
kill -0 "$PID" 2>/dev/null || break
echo "等待进程结束... ($i/5)"
sleep 2
done
# 强制停止(如果仍在运行)
if kill -0 "$PID" 2>/dev/null; then
echo "强制终止进程..."
kill -KILL "$PID" 2>/dev/null
sleep 2
fi
else
echo -e "\n没有jenkins进程在运行,准备启动"
fi
# 启动命令
nohup /usr/local/jvm/java21/bin/java $JAVA_OPTS -jar "$JENKINS_WAR" --httpPort="$PORT" > "$LOG" 2>&1 &
New_PID=`ps -ef | grep '/usr/lib/jenkins/jenkins.war' |grep -v grep |awk '{print $2}'`
[ -n "$New_PID" ] && echo -e "\njenkins启动成功,PID: ${New_PID}" || echo -e "\njenkins启动失败!"