CentOS 7搭建Jenkins+JDK1.8+Maven+Gitee持续集成环境
前阵子帮朋友装一台 CentOS 7 的构建服务器装到一半他就问了一个很多人都会问的问题明明 Jenkins 官网最新版已经到 2.4xx 了为什么教程里还非要指定 2.346这个问题问到点子上了——因为 Jenkins 从 2.346 之后再往上升级就默认要求 Java 11 以上而很多公司线上 Java 项目还在用 JDK1.8。也就是说2.346 系列基本是 JDK1.8 用户能踩的最后一块稳定版本错过了它要么项目升级 JDK要么 Jenkins 就得换启动参数硬扛。今天这篇就把整套流程从头到尾捋一遍涵盖 JDK 1.8、Jenkins 2.346、Maven、Git 和 Gitee 的安装配置目标是你照着敲完就能在浏览器里打开 Jenkins 面板建一个从 Gitee 拉代码、用 Maven 打包的自动化任务。文章里所有命令都在 CentOS 7.x 上实测跑过适合刚接手构建服务器的新手也适合想搞清楚为什么这么配的运维同学。1. 版本选型为什么是 JDK1.8 Jenkins 2.346 这套组合1.1 版本时间线背后藏着的坑先说结论Jenkins 2.346.3 是最后一个官方支持 Java 8 的稳定版本。从 2.347 开始Jenkins 要求最低 Java 11再往后的 2.357、2.361 等版本虽然还能通过调整启动参数在某些 JDK8 环境里勉强跑起来但很多插件开始用 Java 11 的 API 编译运行时会爆 NoSuchMethodError 或者 ClassNotFoundException折腾成本远高于收益。我当时选 2.346 还有另一个原因这个版本对插件生态的兼容性卡在一个很舒服的位置。当时我需要在构建机同时跑多个 freestyle 任务用到的 Git Plugin、Maven Plugin、Gitee Plugin、Timestamper、Build Name and Description Setter 等在 2.346 上都能找到兼容版本号不会出现装完插件后 Jenkins 直接起不来的情况。如果你手头的项目已经升级到 JDK11 甚至 JDK17那完全可以装更新的 Jenkins 版本但如果你的目标就是在 CentOS 7 上给旧项目搭一条稳定的构建流水线那 2.346 系列是最省心的选择。1.2 选错版本会看到什么报错这个值得单独列一节因为很多人装完新版 Jenkins 后启动日志里出现下面这类信息第一反应是JDK 坏了java.lang.UnsupportedClassVersionError: org/apache/tomcat/EmbeddedServletContainer : Unsupported major.minor version 52.0这个报错的含义是Jenkins 运行时代码是用更高版本 JDK 编译的当前 JVM 版本太老读不懂新版 class 文件。反过来如果你用 JDK8 启动 Jenkins 2.400大概率还会在日志里看到类似ERROR: Java 8 is no longer supported. Please run Jenkins with Java 11 or newer.有的版本甚至连这句警告都没有直接崩溃。所以先定版本再定 JDK顺序不能反。1.3 操作系统与硬件前提CentOS 7 官方支持周期早已结束但很多公司的存量服务器仍是它。安装前先用下面命令确认系统cat /etc/redhat-release输出应该是CentOS Linux release 7.9.2009 (Core)之类。内核版本不需要太高但注意32 位系统不能装Jenkins 2.346 需要 64 位 JDK 支持。内存方面如果你打算在同一台机器上跑 Jenkins 和 Maven 构建建议至少 4G 内存只有 2G 的话编译大项目时经常看到 OOM。2. 先把三个前置装明白JDK、Git、Maven 的安装与环境变量很多人装完 Jenkins 后发现找不到 JDK找不到 Maven其实根源不是 Jenkins 的问题而是前置软件本身没装好或环境变量没生效。这一节把三样东西一次说透。2.1 JDK 1.8 的下载与安装CentOS 7 自带的 yum 源里有 OpenJDK很多人图省事直接yum install -y java-1.8.0-openjdk不过 ORACLE JDK 和 OpenJDK 在部分场景下还是有细微差异而且很多公司内部规范指定用 Oracle JDK。如果你也遇到jdk镜像网站找不到jdk这类搜索需求我给你一条稳稳的路径去 Oracle 官网下载jdk-8u202-linux-x64.tar.gz。为什么是 8u202因为这是 Oracle JDK 8 最后一个免费商用版本之后的 8u211 需要商业授权。如果你只是个人学习用下载新一点的 8u3xx 问题不大但公司生产环境建议直接用 8u202。下载完成后传到服务器/opt目录然后执行mkdir -p /usr/local/java tar -zxvf jdk-8u202-linux-x64.tar.gz -C /usr/local/java/ cd /usr/local/java mv jdk1.8.0_202 jdk8我习惯把目录重命名为 jdk8方便后面配置环境变量时少敲几个字符。/opt里的压缩包可以顺手删掉留着也没用。2.2 环境变量配置与找不到 JDK的根因改环境变量文件我用的是/etc/profile因为这是全局生效的位置任何用户登录都能拿到 JDK 路径vim /etc/profile在文件末尾追加export JAVA_HOME/usr/local/java/jdk8 export JRE_HOME/usr/local/java/jdk8/jre export PATH$JAVA_HOME/bin:$PATH export CLASSPATH.:$JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar改完后执行source /etc/profile再验证java -version输出应该显示java version 1.8.0_202。这里有个超级常见的坑source 只对当前会话生效如果你用su -切换到其他用户或者通过 SSH 重新登录新会话才会重新读取/etc/profile。很多教程没说明这一点导致用户明明配好了环境变量打开新窗口又提示找不到 java。另外CentOS 7 系统自带的 OpenJDK 可能先占了alternatives注册表导致java -version指向旧版本。这时候可以用alternatives --config java手动选中你刚装的 JDK8。这一步不是必须的但如果你发现版本不对优先查这里。2.3 Git 安装与基础配置CentOS 7 自带的 yum 源里 Git 版本是 1.8.3.1对拉取 Gitee 仓库来说够用但如果你要用到一些新特性比如git switch、更完善的协议支持建议装新版本。最省事的方式是用 IUS 源。先安装扩展源yum install -y https://repo.ius.io/ius-release-el7.rpm然后yum remove -y git yum install -y git2u装完验证git --version一般会得到git version 2.39.3左右。不装新版本也没关系1.8.3.1 拉代码、切换分支完全够用。为了让 Jenkins 后续操作 Git 仓库更顺利我建议先配置好全局 usergit config --global user.name jenkins git config --global user.email jenkinsexample.com很多初学教程不会提这一步但如果不配某些 Git 插件在做 commit 类操作时会直接报错。2.4 Maven 安装与阿里云镜像配置Maven 的安装和 JDK 类似下载二进制包解压即可。我选用的是apache-maven-3.6.3这个版本是 Maven 3 系列里口碑最好的稳定版之一和 JDK8 配合没有任何兼容问题。mkdir -p /usr/local/maven tar -zxvf apache-maven-3.6.3-bin.tar.gz -C /usr/local/maven/ cd /usr/local/maven mv apache-maven-3.6.3 maven363环境变量vim /etc/profile追加export MAVEN_HOME/usr/local/maven/maven363 export PATH$MAVEN_HOME/bin:$PATHsource /etc/profile后执行mvn -v重点不是看版本号而是确认它正确读到了 JDK 路径。输出里会显示Java version: 1.8.0_202这才算配好。接下来务必配置阿里云镜像不然下载依赖能让你等到怀疑人生。修改 Maven 的核心配置文件settings.xmlvim /usr/local/maven/maven363/conf/settings.xml在mirrors标签里添加mirror idaliyunmaven/id mirrorOfcentral/mirrorOf name阿里云公共仓库/name urlhttps://maven.aliyun.com/repository/public/url /mirror同时建议把默认本地仓库位置改到自定义目录避免在很小的系统盘里堆满 jar 包。我一般改成localRepository/data/maven-repo/localRepository记得先创建/data/maven-repo目录并给当前用户写权限。配完镜像后随便建一个新的空 Maven 项目跑一次mvn compile几秒钟内就能看到依赖开始下载速度很快说明镜像生效了。3. Jenkins 安装与首次初始化war 包还是 yum怎么选3.1 下载 war 包这种方式的优势Jenkins 安装有两条主流路径一条是用官方 yum 源直接装 RPM另一条是下载 war 包用java -jar启动。我在 CentOS 7 上更推荐 war 包方式原因有三个不受 yum 源里的版本号限制想要哪个版本下哪个版本升级只是替换一个文件回滚也简单用java -jar启动时JVM 参数完全自己控制比如设置时区、调整堆内存。下载地址是清华镜像站速度比官方快很多mkdir -p /opt/jenkins cd /opt/jenkins wget https://mirrors.tuna.tsinghua.edu.cn/jenkins/war-stable/2.346.3/jenkins.war官网地址虽然也能下但国内服务器经常几十 KB/s清华镜像能跑到几 MB/s。3.2 第一次启动解锁密码和初始化插件启动前先创建一个普通用户我习惯用 jenkins 用户专门跑服务避免直接用 root 带来的权限问题useradd jenkins chown -R jenkins:jenkins /opt/jenkins然后切换到 jenkins 用户启动su - jenkins -c java -jar /opt/jenkins/jenkins.war --httpPort8080 /opt/jenkins/jenkins.log 21 第一次启动会自动执行初始化流程日志文件里能看到类似Jenkins initial setup is required. An admin user has been created and a password generated. Please use the following password to proceed to installation:这条密码也可以从/var/lib/jenkins/secrets/initialAdminPassword里读。用 war 包方式启动时Jenkins 默认数据目录在~/.jenkins所以如果你以 jenkins 用户启动路径就是/home/jenkins/.jenkins/secrets/initialAdminPassword。打开浏览器访问http://服务器IP:8080输入密码后进入插件安装选择页。这里我的建议是不要选安装推荐插件选选择插件来安装。不是推荐插件不好而是国内网络环境下载全部推荐插件很容易超时失败一会儿这个红一会儿那个失败反而让人烦躁。我通常会只勾选这几类Git PluginMaven Integration PluginGitee PluginTimestamperBuild Name and SetterCredentials Binding后面需要什么再通过Manage Plugins补齐这是最稳的策略。3.3 把插件源换成国内镜像这一步必须做不管你是选了推荐插件还是自己挑插件安装过程都可能卡在某一个插件上下载失败。究其原因Jenkins 官方插件中心在国外国内服务器访问不稳定。解决办法是修改 Update Site 地址。点击 Jenkins 主界面左侧的Manage Jenkins进入Manage Plugins再点Advanced标签页最下方有一个Update Site输入框默认值是https://updates.jenkins.io/update-center.json将它替换为清华镜像https://mirrors.tuna.tsinghua.edu.cn/jenkins/updates/update-center.json保存后点击Check now强制刷新插件索引再去安装插件会发现成功率高得多。这一步网上到处都在讲但很多人漏了保存后重启 Jenkins 这个动作索引刷新有时不会立即生效。4. 把 JDK、Maven、Git 接进 Jenkins全局工具配置的核心逻辑4.1 Global Tool Configuration 里到底该填什么安装完 Jenkins进入Manage Jenkins-Global Tool Configuration。这一步是连接系统里的 JDK/Maven/Git和Jenkins 插件调用的桥不配或配错后面建任务时就会遇到找不到 JDK的经典报错。JDK 栏目不要勾选Install automatically因为我们的 JDK 已经手工装好了自动安装会让 Jenkins 自己去下载一个它认得的 JDK既慢又和系统现有的冲突。手动填写Name: jdk8JAVA_HOME:/usr/local/java/jdk8这里很容易遇到一个问题Jenkins 要求填的JAVA_HOME不是/usr/bin/java而是 JDK 安装目录的根路径。如果你填成/usr/bin保存后测试构建时会报The specified JDK location does not appear to be a valid Java installation directory因为/usr/bin下面只有软链接并不是真正的 JDK 家目录。Maven 栏目同样取消Install automatically手动填Name: maven363MAVEN_HOME:/usr/local/maven/maven363Git 栏目这里比较简单填可执行文件路径即可Path to Git executable:/usr/bin/git如果你是用 IUS 源装的 git2u路径一般还是/usr/bin/git不用担心。验证 git 配置是否正确可以登录服务器直接执行which git把结果填进去就行。4.2 自动安装这个选项为什么劝你慎用很多人第一次看到Install automatically复选框时觉得方便勾上之后 Jenkins 就能自动下载 JDK 和 Maven。我在 2.346 上实测过这个功能体验并不好自动安装 JDK 时Jenkins 会去 Oracle 官网下载且不支持 JDK8 的免费版本容易因为网络问题直接失败自动安装 Maven 时下载的是 Maven 3.8 之后的版本如果系统 JDK 是 1.8可能不兼容自动安装目录藏在 Jenkins 部署目录内部升级时容易丢失。所以结论很明确手动装的 JDK、Maven、Git在全局工具配置里手动填好路径是最可控、最容易排查错误的方式。4.3 配置完后的验证小技巧配置完不要急着去建任务可以先在 Jenkins 的系统信息页面看环境变量。路径是Manage Jenkins-System Information。在列表里搜索JAVA_HOME、MAVEN_HOME如果能看到你在/etc/profile里设置的值说明 Jenkins 进程正确读取了环境变量如果显示为空说明 Jenkins 启动时没有加载/etc/profile这就解释了为什么很多人的构建任务里无法调用 mvn 命令。遇到这种情况可以在启动 Jenkins 的 JVM 参数里显式加上-DMAVEN_HOME/usr/local/maven/maven363 -DJAVA_HOME/usr/local/java/jdk8虽然不算优雅但能救急。5. 把 Gitee 源码仓库接入 Jenkins凭证与 Webhook 打通5.1 安装 Gitee 插件与系统级配置Gitee 官方提供 Jenkins 插件在插件管理里搜索Gitee Plugin安装即可。装完后进入Manage Jenkins-Configure System找到Gitee配置项。这里需要填两部分内容Gitee link URL填写https://gitee.com/api/v5/Gitee 名称填gitee.com或你自己的标识Credential点击添加 - Jenkins类型选择Username with passwordGitee 的密码建议使用私有令牌而不是登录密码。生成方式是Gitee 网站右上角头像 - 设置 - 私人令牌 - 生成新令牌。权限上勾选projects和hooks就足够 Jenkins 拉代码和创建 Webhook 用了。我把用户名填 Gitee 用户名密码填私人令牌实测可用。5.2 仓库凭证的两种姿势HTTPS 密码与 SSH 密钥Gitee 配置好系统级凭证后创建任务时还需要针对具体仓库提供访问凭证。如果你是个人项目直接用 HTTPS 用户名密码方式最快。在任务的源码管理选 Git仓库 URL 填https://gitee.com/你的用户名/你的仓库.git凭证选择你刚创建的Username with password那一项。注意这里的用户名必须是 Gitee 的真实用户名不能是邮箱虽然部分情况邮箱也支持但有的仓库权限匹配会有问题。另一种方式是 SSH。服务器上生成密钥对su - jenkins ssh-keygen -t rsa -b 4096 -C jenkinsexample.com cat ~/.ssh/id_rsa.pub然后把这串公钥添加到 Gitee 仓库的管理 - 部署公钥里。这样做的好处是不依赖密码构建机换密码也不影响拉代码。我个人更推荐 SSH 方式因为 Jenkins 构建任务经常还会涉及 clone 私有子模块或 push 构建产物SSH 权限管理更干净。5.3 Webhook 自动触发构建配置要让开发者往 Gitee 推送代码后自动触发构建需要配置 Webhook。前提是 Jenkins 所在的服务器能让 Gitee 公网访问到。如果你的是内网服务器这一步需要运维协助做端口映射8080端口必须能从外网访问。具体配置路径进入目标任务 -构建触发器- 勾选Gitee webhook触发构建页面会生成一个 Webhook URL类似http://你的Jenkins地址/gitee-project/任务名打开 Gitee 仓库 - 管理 - WebHooks - 添加 WebHookURL 填 Jenkins 生成的地址密码可以不填默认勾选Push事件即可。配置完成后点 Gitee 那边的测试如果提交表单里返回200说明 Gitee 能正常访问到 Jenkins。如果你的机器有防火墙记得开放 8080 端口firewall-cmd --permanent --add-port8080/tcp firewall-cmd --reload如果是云服务器还要在安全组里放行 8080。6. 第一个 Maven 构建任务从创建到跑通6.1 创建自由风格任务并拉取代码点击首页左上角新建任务输入任务名称比如demo-build选择构建一个自由风格的软件项目点确定。在源码管理里选 Git仓库地址填 Gitee 仓库地址凭证选刚才创建的凭证。分支构建器填*/master或*/main取决于你的项目主分支叫什么。填写后可以先点界面上的加载按钮如果能看到分支列表说明网络和凭证都没问题。这时候可以先手动触发一次构建但先别急因为还没有配构建步骤。等配完构建步骤后再手动构建一次才能看到完整流程。6.2 配置 Maven 构建步骤往下找到构建环境我一般勾选Add timestamps to the Console Output给日志加时间戳排查问题很方便Color Console Output让日志有颜色眼睛友好一些。然后在构建区域点增加构建步骤选择Invoke top-level Maven targets。Maven 版本选maven363目标里写clean package -DskipTests这里有一个小细节如果你直接把-DskipTests放进去Jenkins 会把它作为 Maven 参数处理但要保证它是在clean package后面否则会被当成 Maven 自身参数。大多数情况下上面写法没问题但如果你要做更复杂的参数传递建议把-DskipTests放到Advanced选项里的Properties中。保存后点立即构建。第一次构建会下载大量依赖耗时取决于依赖数量和网速一般 3~10 分钟不等。构建过程中可以点击构建号查看Console Output重点看是否出现BUILD SUCCESS。6.3 构建完的产物去哪了工作空间目录解析很多新手构建成功后找不到 jar 包。默认情况下Jenkins 的任务工作空间在/home/jenkins/.jenkins/workspace/任务名/Maven 打包产物在/home/jenkins/.jenkins/workspace/任务名/target/xxx.jar在任务页面左侧点击工作区可以直接浏览目录结构。如果你折腾过 docker 部署、云服务器路径映射会发现这个目录结构是后续一切自动化发布的基础——无论是 SSH 传到应用服务器还是打进 Docker 镜像都要从这里拿产物。我一般会在构建后操作里选择Archive the artifacts写target/*.jar这样每次构建完成后Jenkins 会在构建历史页面上提供一个可下载的 jar 包链接后续即使工作空间被清理历史产物也能找回来。7. 我实测踩过的一堆坑内存、权限、时区、找不到 JDK7.1 堆内存和 JVM 参数优化CentOS 7 服务器内存动辄只有 2G 或 4GJenkins 默认 JVM 堆大小是按物理内存比例算出来的很可能开完 Jenkins 后再跑 Maven 构建就 OOM。建议启动 Jenkins 时显式指定 JVM 参数java -Xms256m -Xmx1024m -jar /opt/jenkins/jenkins.war --httpPort8080-Xms是初始堆大小-Xmx是最大堆。给 Jenkins 1G 堆对大多数中小项目来说够用了剩下内存留给 Maven 构建子进程。如果你的构建任务特别多可以给到 1.5G 或 2G但 4G 内存的机器不建议超过 2G否则 Maven 那边的启动速度会受影响。如果你是用systemd或crontab方式启动更优雅的做法是把参数写进 service 文件里。我习惯写一个/etc/systemd/system/jenkins.service方便开机自启[Unit] DescriptionJenkins Server Afternetwork.target [Service] Userjenkins ExecStart/usr/local/java/jdk8/bin/java -Xms256m -Xmx1024m -Duser.timezoneAsia/Shanghai -jar /opt/jenkins/jenkins.war --httpPort8080 Restarton-failure [Install] WantedBymulti-user.target然后systemctl daemon-reload systemctl enable jenkins systemctl start jenkins7.2 时区问题构建日志时间和 Gitee 提交时间对不上默认情况下CentOS 7 时区可能是 UTC导致 Jenkins 构建记录显示的时间和 Gitee 上的提交时间差 8 小时。判断起来很费劲尤其排查用户 push 了代码但 webhook 没触发时两边时间对不上会误导方向。在 systemd 文件里加-Duser.timezoneAsia/Shanghai是最直接的办法也可以在系统层把时区改掉timedatectl set-timezone Asia/Shanghai改完后 Jenkins 控制台输出的时间戳就和 Gitee 保持一致了。7.3 目录权限build 时提示 Permission deniedJenkins 是以jenkins用户身份运行的所以MAVEN_HOME、JAVA_HOME指向的目录以及/data/maven-repo本地仓库目录都必须是 jenkins 用户可读可写的。如果不放心直接授权chown -R jenkins:jenkins /usr/local/java/jdk8 chown -R jenkins:jenkins /usr/local/maven/maven363 chown -R jenkins:jenkins /data/maven-repo这里有个经验之谈直接用chmod -R 777虽然能解决一时问题但在多用户服务器上会引入不必要的安全风险我遇到过有人把整个/usr/local都777之后其他服务就莫名出现配置文件被篡改的情况。7.4 其他常见报错速查表下面的表格是我从多台服务器上搜集到的典型问题和解决方案遇到报错时可以拿来对照报错 / 现象根本原因解决办法Jenkins 页面打不开8080 端口没放行 / jenkins 进程没起来netstat -tlnp构建时mvn: command not foundJenkins 进程没加载/etc/profile里的 Maven 路径全局工具配置里用绝对路径别依赖 PATH拉取 Gitee 代码时Authentication failed凭证填错 / Token 权限不足重新生成私人令牌勾选 projects 权限Webhook 测试返回 403设置了 CSRF 保护且来源不符Jenkins 里关闭 CSRF 或配置允许的代理来源构建后找不到 jar 包项目打包名称和路径与预期不一致检查target目录用Archive the artifacts固定路径插件安装失败 / 下载超时默认 Update Site 在国内网络不通改成清华镜像源后重试控制台日志中文乱码系统 locale 和字符集问题启动参数加-Dfile.encodingUTF-87.5 一个小技巧查看构建日志里的可疑失败原因很多时候卡在某个步骤Console Output 里一堆红色日志但又不知道哪里开始出的问题。我习惯在 Console Output 页面直接按CtrlF搜索ERROR、FAILURE、Caused by。Caused by往往指向最底层异常比一屏的堆栈信息更有用。比如常见的Caused by: java.io.IOException: Cannot run program mvn看到这个基本就是环境变量的问题不用去翻几十行之前的信息。另外如果构建日志刷得太快看不到关键内容可以在任务配置里勾选Abort the build if its stuck在构建环境中设置一个超时时间比如 10 分钟无输出就自动结束。这能避免一次卡死的构建占用 Jenkins 进程池导致后面任务排队。最后再分享一个我在实际使用中的体会刚接触 Jenkins 时总想一股脑把自动部署、邮件通知、SonarQube 质量门禁全配上结果出了问题时根本不知道是哪一环出的幺蛾子。后来我把这套环境收敛成只拉代码、只打 Maven 包、产物归档跑通之后再加 Webhook 自动触发再往后面才去接 SSH 远程部署。每一层都验证无误后再叠加下一个功能排查问题的范围就能缩得很小。你如果第一次在 CentOS 7 上搭 Jenkins也建议按这个节奏来先把基础链路走通后面再加花活。
上一篇/下一篇内容由系统自动关联
返回资讯列表 →