拓冰建站拓冰建站
首页 / 资讯中心 / 正文

Jenkins入门实战:从安装配置到Pipeline自动化构建

我第一次接触Jenkins是在一个项目上线前夕。当时后端同事每次发版都要手动跑到服务器上执行一堆命令打包、停服、拷贝、重启运气好十分钟运气不好半小时起步。后来有人提议把这一切交给Jenkins我才开始认真研究这个工具。Jenkins本质上是一个自动化调度平台说得直白一点它是一个只管按计划执行任务的中间人什么时间、在什么机器上、执行什么命令、产出了什么结果都由它统一管理。你不需要一开始就懂CI/CD那些术语先把Jenkins当成一台能帮你自动执行发布流程的服务器来看待理解起来会容易得多。这篇文章不是官方文档式的介绍也不是鼓吹Jenkins多么厉害的推广文而是一个从零接触Jenkins的人把安装、配置、建任务、写流水线、配通知、排错这些环节里最有价值的东西记录下来。如果你刚接触Jenkins或者在公司接手了一个已经搭好的Jenkins但完全不知道怎么下手这篇文章应该对你有用。1. Jenkins到底是个什么东西从一次手工发版说起1.1 手工发版的痛先还原一个非常常见的场景。项目开发完成后开发者把代码push到代码仓库然后通知运维或负责发布的人可以发了。发布人打开终端登录服务器进入项目目录拉取最新代码执行mvn package如果编译失败还得回头找开发排查。编译通过之后再把war包或jar包拷贝到应用目录停掉旧进程启动新进程然后看一眼日志确认启动正常。这个过程听起来不算复杂但只要是操作次数一多问题就来了。比如上周能用的一整套命令今天因为某个配置文件被改动突然不能用了比如A服务器和B服务器的环境不一样同样的命令在不同机器上跑出不同结果再比如凌晨两点的紧急发版睡眼惺忪地敲错一个命令后果更加麻烦。Jenkins解决的核心问题就是把重复、机械、容易出错的手工操作变成一旦配置好就能稳定执行的自动化流程。1.2 顺带讲清楚CI/CD很多人第一次看到Jenkins都被持续集成持续交付持续部署这几个词劝退了。其实没那么玄。持续集成英文是Continuous Integration核心动作是频繁地把代码集成到主干每次集成都自动编译、测试让问题尽早暴露。持续交付是在持续集成基础上把产物发布到类生产环境保证随时可以上线。持续部署则是更进一步代码通过所有检查后自动部署到生产环境全程不需要人点按钮。这三者的关系可以类比成做饭持续集成相当于每次炒完一个菜都自己尝一口确认没炒糊持续交付相当于把菜端到桌上、客人随时可以动筷子持续部署相当于连请慢用都不用说菜一上桌大家自己开吃。Jenkins在整个链路里不是做饭的人而是那个提醒你该尝菜了该上菜了的闹钟和计时器同时还能帮你把定时要做的事记下来到点自动执行。1.3 Jenkins的好帮手插件体系和生态Jenkins之所以能成为CI/CD领域最常见的工具之一很大程度靠的是它的插件生态。Git、GitLab、Gitee、Maven、Gradle、Docker、Kubernetes、钉钉、飞书、企业微信、邮件、SonarQube……几乎你能想到的常见工具都能找到对应的插件。这也让Jenkins从一个能执行任务的引擎变成了什么都能接的万能中转站。不过插件多也有多的烦恼。插件版本和Jenkins核心版本不匹配是初学者最容易遇到的坑之一。后面我会专门讲插件报错的问题。2. 一台能用的Jenkins安装部署的细节与坑2.1 先决定装哪个版本打开Jenkins官网下载页默认会有两个版本推荐Weekly版本和LTS长期支持版。很多教程直接让你装最新weekly版但我的建议很明确没有特殊需求就装LTS尤其是生产环境。原因很简单weekly版本虽然功能更新更快但新功能通常伴随新问题。LTS版本每12周会从weekly版本线中挑选一个稳定版本之后持续修bug适合不想频繁折腾的人。我最初就是在CentOS 7上装了当时最新的weekly版本结果一个插件始终装不上换回LTS之后一切正常。2.2 在CentOS 7上安装Java版本是第一道门槛CentOS 7自带的JDK版本通常比较老而新版Jenkins从2.357左右开始要求Java 11或17。如果你用系统自带的OpenJDK 1.8去启动大概率会直接报错。推荐的安装顺序是这样检查当前Java版本java -version如果没有Java 11或17先装一个。CentOS 7上可以用yum安装OpenJDK 11sudo yum install -y java-11-openjdk导入Jenkins仓库并安装sudo wget -O /etc/yum.repos.d/jenkins.repo https://pkg.jenkins.io/redhat-stable/jenkins.repo sudo rpm --import https://pkg.jenkins.io/redhat-stable/jenkins.io-2023.key sudo yum install -y jenkins启动并设置开机自启sudo systemctl start jenkins sudo systemctl enable jenkins这段流程看起来没什么但容易出问题的点在于repo的GPG key地址。早期的教程给的key链接和新的不一样如果你照着旧教程安装会报public key not available之类的错误。遇到这个问题不用慌去官方仓库页找最新版本的key文件地址重新导入即可。2.3 用Docker部署更省心但要注意数据目录如果你的服务器上已经有Docker环境用容器跑Jenkins也是一种非常常见的方案。官方镜像名为jenkins/jenkins以LTS为例docker run -d \ --name jenkins \ -p 8080:8080 \ -p 50000:50000 \ -v jenkins_home:/var/jenkins_home \ --restartalways \ jenkins/jenkins:lts-jdk17这里有个关键点一定要挂载一个volume到/var/jenkins_home。Jenkins的所有配置、插件、构建记录都存放在这个目录里如果不挂载容器一删除所有东西就全没了。还有一个很多人没注意到的点如果Jenkins容器内需要执行docker命令比如在流水线里构建镜像并推送需要挂载宿主机的docker.sock也就是典型的docker in docker方案。不过新手阶段不用急着搞这个先把构建跑通再慢慢玩容器化。另外Docker镜像下载慢是另一个很现实的问题。如果你在公网环境拉取镜像速度不理想可以配置Docker的镜像源加速。注意选择当前网络环境下实际可用的镜像源地址这是常规操作不展开讲了。2.4 首次启动初始密码和插件安装卡住Jenkins第一次启动后访问http://服务器IP:8080会要求输入初始管理员密码。这个密码在服务器上有对应的文件可以用命令查看sudo cat /var/lib/jenkins/secrets/initialAdminPassword如果是在Docker容器中docker exec jenkins cat /var/jenkins_home/secrets/initialAdminPassword输入密码之后进入插件安装界面。新手很容易卡在这一步默认安装插件然后进度条一直转甚至报网络错误。这通常是源的问题。解决办法有两个方向一是换镜像源也就是把Jenkins的update center改成可访问的镜像站点二是先跳过插件安装进入系统后到插件管理里手动逐个安装这样至少能看到哪一步失败、失败原因是什么不会一卡十几分钟。3. 新装的Jenkins先别急着建任务这些基础配置决定上线体验3.1 设置中文界面新版本Jenkins本身支持中文语言包只是默认没有启用。安装语言插件之后在系统管理-外观里把语言改为zh_CN刷新页面即可。很多教程让人用旧方法去改locale其实新版本在系统设置里直接改就行方便很多。需要提醒的是界面中文化之后很多配置项的中文翻译并不完全准确对排错理解可能反而造成困扰。我的建议是如果你刚开始学中文界面能降低心理门槛但遇到问题时切回英文界面再看一眼具体报错会更有帮助。3.2 用户、权限和管理员为什么只能用admin很多人刚装好Jenkins就一直用admin账号。这在小范围测试阶段没问题但如果团队要一起用就必须做好用户和权限规划。Jenkins默认提供基于数据库的用户管理也可以接入LDAP或者GitLab的OAuth。对于中小团队最简单的方案是给每个成员单独建账号按项目分配构建权限。这里有一个非常基础但重要的概念Jenkins的角色分为全局角色、项目角色和节点角色。全局角色管理的是系统级操作权限比如系统配置、插件安装项目角色管理的是某个项目或某些项目通过正则匹配的构建权限节点角色管理的是构建节点的执行权限。刚开始不用配置得特别细但至少应该做到普通成员只能操作自己的项目不能修改系统设置。如果所有人的账号都是admin那一次误操作可能让整个Jenkins平台都瘫痪。3.3 插件选择与控制装得越多风险越大Jenkins的插件管理逻辑是用到什么装什么而不是能装什么装什么。插件越多内存占用越高插件间冲突的可能性也越大。对于基本的Java后端项目持续集成我通常建议先装这些Git插件、Maven Integration插件、Pipeline插件、Email Extension插件邮件通知用、Credentials Binding插件凭证管理、Blue Ocean插件可视化流水线界面。Docker相关、Kubernetes相关、飞书钉钉通知这些等真实需要时再添加。安装插件时经常会遇到插件兼容性警告Jenkins会列出哪些插件与当前核心版本或现有插件存在依赖冲突。看到这种警告一定要认真判断如果只是提示这个插件要求Jenkins版本高于当前版本那升级Jenkins或者换一个兼容版本即可如果是插件之间互相依赖冲突那就要考虑是不是必须同时装上。3.4 全局工具配置JDK、Maven的版本统一在系统管理-全局工具配置里可以配置JDK和Maven。新手容易犯的错误是在服务器上手工装了JDK和Maven就以为Jenkins能直接用来执行mvn命令。其实Jenkins在构建任务里使用JDK和Maven需要在这里做关联配置。有两种方式一种是自动安装让Jenkins自己下载JDK和Maven版本这种方式依赖外网访问离线环境一般不适用另一种是本地安装指定服务器上已有的JDK和Maven路径。我比较推荐后者因为版本可控且不依赖网络。路径填好后建议保存设置时顺手检查一下Jenkins报错信息很多人在这一步填错了路径构建时才发现命令找不到。3.5 凭证管理不要干出把密码写在脚本里这种事Jenkins里有专门的凭证管理功能Credentials。从Git拉取代码要用的账号密码、SSH密钥要调用第三方API的token都应该存成凭证然后在构建任务或Pipeline里引用。创建凭证的位置在系统管理-凭证-系统-全局凭证。以Git仓库的账号密码为例类型选择Username with passwordUsername填写Git平台的账号Password填写密码或访问令牌ID这一项建议填一个容易识别的名字后面引用时要用使用凭证时在构建任务源码管理里选择对应的凭证即可。这样做的最大好处有两个一是密码不会明文出现在Jenkinsfile或构建日志里二是换密码时只需要在Jenkins里改一次不用去每个脚本里找。4. 第一个有意义的构建任务后端项目的mvn打包与发布4.1 配置一个拉代码—构建—发布的完整任务假设你有一个Maven构建的Java后端项目目标是每次代码push后自动打jar包并部署到指定服务器。这里我以FreeStyle项目为例因为它的界面化配置对新手最友好。创建任务的步骤大致是点击新建Item输入任务名称选择Freestyle project在源码管理里选择Git填写仓库地址选择凭证在构建触发器里勾选需要的触发方式比如定时构建H/5 * * * *表示每5分钟检查一次或Webhook触发在构建环境里按需勾选Delete workspace before build starts等选项在构建里选择Invoke top-level Maven targetsGoals填clean package保存后点击立即构建第一次构建时控制台输出会很多新手看到一堆日志容易慌张。其实只需要关注几个关键节点拉代码是否成功通常有Checking out Revision等字样、mvn编译是否成功BUILD SUCCESS或BUILD FAILURE、产物是否生成。4.2 Webhook触发让代码push后自动构建配置Webhook是实现push代码自动触发构建的标准方式。以Gitee或GitLab为例需要在仓库管理后台找到Webhook设置页面填入Jenkins的触发器地址。这个地址的格式通常是http://你的Jenkins地址/project/任务名或者使用Gitee插件之后有专门的推送路径。需要注意域名问题代码仓库服务器必须能通过网络访问到你的Jenkins地址。如果Jenkins在内网而代码仓库在公网那么要么做内网穿透要么改用定时轮询的方式触发。首先需要让Jenkins的特定任务准备好接收Webhook通知这句话说得非常准确。接收Webhook的关键有三点任务里必须勾选对应的触发器选项Jenkins端已经装了对应的Webhook插件仓库里配置的URL和密钥要和Jenkins里的一致。三样缺一不可任何一个对不上push之后控制台都毫无反应。4.3 Jenkins可用环境变量构建时最实用的变量Jenkins在构建过程中会自动注入一批环境变量这些变量在做发布脚本时非常有用。常用的一些BUILD_NUMBER构建号JOB_NAME任务名称BUILD_URL本次构建的详情页地址GIT_COMMIT当前构建的Git提交IDGIT_BRANCH当前构建的分支WORKSPACE工作目录BUILD_USER_ID触发构建的用户在Shell构建步骤里可以直接用echo $BUILD_NUMBER打印这些变量。在Pipeline里可以通过env.BUILD_NUMBER访问。我已经记不清有多少次在发布脚本里需要用到本次是第几次构建或者当前在哪个目录如果不知道这些变量就只能写死路径或手动填参数一旦任务名称或路径变化脚本就废了。另外如果你想自定义一些参数可以在构建任务里配置参数化构建添加字符串参数或选项参数。这样每次手动构建时都有下拉框或输入框配合环境变量可以实现一条流水线测试/正式环境通用。4.4 控制台日志显示不全怎么完整查看构建输出很多人在Jenkins控制台里看到长长的日志想往上翻却只看到部分内容或者日志被截断。Jenkins默认的日志显示确实有渲染和折叠逻辑页面刷得慢、日志过长时看起来就像显示不全。这种情况下最靠谱的办法是直接查看原始日志文件。在构建详情页的左侧菜单里找到Console Output有些版本可以直接在页面上选择完整日志或按时间段查看。如果你登录服务器可以进入/var/lib/jenkins/jobs/任务名/builds/构建号/log直接把整个原始日志打印出来用grep过滤关键字比在网页上翻边不仅快还不容易漏。我在排查构建失败问题时经常直接下载log文件然后搜索ERROR或FAILURE效率高很多。4.5 一个可落地的发布脚本思路构建产物有了之后如何发布到目标服务器新手常见的做法是直接在构建任务的构建步骤里写一堆Shell命令把打包、拷贝、启动全塞进去。这样能跑通但有个问题命令全写在Jenkins配置里不便于版本管理也不便于复用。更好的做法是把发布逻辑写成一个独立的shell脚本放在代码仓库的deploy目录下然后在Jenkins的构建步骤里执行chmod x deploy/deploy.sh ./deploy/deploy.sh ${WORKSPACE}/target/app.jar脚本内部做这几件事备份旧版本、拷贝新包、停止旧进程、启动新进程、检查健康状态。这里最重要的一个原则是先备份再替换失败可回滚。哪怕团队很小这条规则也一定要守住。5. Pipeline把构建过程从点鼠标变成写代码5.1 为什么从一开始就应该接触PipelineFreestyle任务好理解但有一个致命缺点所有配置都绑定在Jenkins的页面上无法随着代码一起做版本管理。如果哪天Jenkins数据丢失或者你想在新环境重建一套同样的构建流程只能对着截图和记忆一步步重新配置。Pipeline把构建过程写成了代码通常放在Jenkinsfile文件里跟项目代码一起放在Git仓库中。这样做的好处非常明显流程变更走代码评审环境迁移只需要拉代码建任务每个人看到的构建过程都是同一份定义不会有我这边任务配置和你那边不一样的混乱。对于一次一点点了解Jenkins的学习过程我认为从Freestyle入门是为了理解配置项对应什么功能但越早转入Pipeline你的收益越大。5.2 最小可用的Declarative Pipeline示例Declarative Pipeline是现在最推荐的写法它的语法结构清晰适合大多数场景。下面是一个最简单的示例pipeline { agent any environment { PROJECT_NAME demo-app } stages { stage(拉取代码) { steps { checkout scm } } stage(编译打包) { steps { sh mvn clean package -DskipTests } } stage(发布) { steps { sh ./deploy/deploy.sh } } } post { success { echo 构建成功 } failure { echo 构建失败 } } }这段代码的含义是在任何可用的agent节点上执行定义了一个环境变量然后依次执行拉代码、编译、发布三个阶段最后在构建结束后根据结果输出不同信息。5.3 stage、agent、environment的实用理解刚接触Pipeline时不需要掌握所有语法先理解三个核心关键词就够用agent定义流水线在哪个节点上执行。agent any表示任意可用节点有多个执行节点时可以指定agent { label backend }把任务放到指定标签的机器上跑。environment用来声明环境变量作用域可以是全局的也可以限定在某一个stage内。比如在发布阶段设置DEPLOY_ENVprod只在发布那个stage里生效。stage定义流水线的阶段每个阶段可以包含多个steps。阶段划分的目的不只是逻辑清晰更是在界面上能看到哪一步挂了Blue Ocean里尤其直观。还有一个小建议Pipeline里执行Shell命令时尽量把关键的参数用环境变量引用出来而不是写死在命令里。这样后续改动只需改一处。5.4 Blue Ocean可视化Pipeline的友好界面Blue Ocean是Jenkins官方推出的一套新的用户界面专门优化了Pipeline的可视化体验。安装Blue Ocean插件后打开Open Blue Ocean可以看到每个阶段以卡片形式展示绿色为成功红色为失败点进去可以直接看到该阶段的日志。排查流水线失败时不用再一长串日志里翻找定位会快很多。Blue Ocean不是替代Jenkins系统管理功能它更偏向于查看构建状态和操作Pipeline任务。系统管理、插件安装这类功能仍然在经典界面里完成。6. 构建失败通知从邮件到飞书别让构建结果烂在Jenkins里6.1 邮件通知的配置构建失败如何发送邮件是搜索热度很高的问题。Jenkins内置的邮件通知功能非常基础而更实用的是Email Extension插件简称Email-ext它允许你自定义邮件的收件人、主题和内容模板。配置步骤大致是安装Email Extension插件在系统管理-系统设置里配置SMTP服务器信息比如你公司邮箱的SMTP在Extended E-mail Notification里填写默认收件人、主题和内容模板在构建任务的后置操作Post-build Actions里添加Editable Email Notification第一次测试邮件时有一个很容易忽略的点发件人邮箱需要和SMTP认证账号一致否则服务器可能拒绝发送。另外很多邮箱默认开启了客户端授权码机制直接在Jenkins里填登录密码发不出去需要去邮箱设置里生成一个授权码。6.2 飞书通知用Webhook机器人把构建结果推到群里如果你的团队用飞书配置构建通知的思路和邮件类似但更轻量。只需要在飞书群里创建一个自定义机器人得到一个Webhook地址然后在Jenkins任务里用脚本或插件把消息POST到那个地址即可。最简单的方式是在Pipeline的post阶段写一段curl命令post { failure { sh curl -X POST -H Content-Type: application/json \ -d {msg_type:text,content:{text:构建失败: ${JOB_NAME} #${BUILD_NUMBER}}} \ 你的飞书Webhook地址 } }实际使用时建议把通知逻辑封装成一个公共方法或单独的脚本避免在每个Pipeline里重复粘贴一大段JSON。消息内容里至少应该包含任务名称、构建号、失败/成功的阶段、BUILD_URL链接。这样群里收到通知的人可以直接点链接去看日志不用再问哪个任务挂了。6.3 通知内容设计让人看到消息就知道该怎么办通知不是简单地把成功/失败两个字丢给群成员就完了。一个合格的构建通知应该包含三类信息结果哪个任务、哪个构建号、成功还是失败、位置构建详情页的链接、原因失败的阶段或关键错误日志摘要。如果你的团队有固定的发布窗口或者值班制度还可以在通知里带上触发者信息。Jenkins环境变量里的BUILD_USER_ID可以拿到触发这次构建的人是谁把这个人写进通知责任归属一目了然。7. 安全上不能偷懒未授权访问漏洞和权限收口7.1 一个危险的默认状态Jenkins在首次启动时默认不启用安全控制也就是说安装完成之后的几分钟内任何人都能访问你的Jenkins页面、查看构建任务、甚至执行构建。如果你的Jenkins暴露在公网又没有及时配置安全设置那基本就是把门敞开放在大街上。Jenkins未授权访问漏洞在安全圈里是一个被反复提到的典型问题。攻击者利用未授权访问可能获取到Jenkins控制台、查看构建日志中的敏感信息比如脚本里不小心写进去的密码甚至通过配置恶意任务执行系统命令。这不是危言耸听而是真实发生过的攻击路径。7.2 最小且有效的安全配置清单在完成基础安装后至少要做这几件事在系统管理-全局安全配置中将授权策略从任何用户可以做任何事改为登录用户可以做任何事并关闭允许用户注册也就是不允许自助注册账号为管理员设置强密码不要把默认的initialAdminPassword一直沿用下去修改默认端口或限制访问来源比如用防火墙只允许公司IP访问8080端口定期升级Jenkins版本和插件版本不要一等半年不管如果配置了SSH到目标服务器的功能严格管理Jenkins端保存的SSH密钥遵循最小权限原则这些措施每一条都不复杂但组合起来能挡掉大部分基础攻击。不要觉得我们团队小没人盯着自动化攻击脚本可不管团队大小。8. 常见问题排查小抄这些报错我基本都遇到过8.1 unable to find valid certification path to requested target这个报错非常常见通常出现在安装插件、访问HTTPS地址时。核心原因是Jenkins所在服务器的JDK证书库中不包含目标站点SSL证书的根证书。说白了就是JDK不认识这个HTTPS站点的证书。常见解决办法是在目标站点导出证书并导入JDK的cacerts证书库。以JDK 11为例命令大致是keytool -import -alias 别名 -keystore /usr/lib/jvm/java-11-openjdk/lib/security/cacerts -file 证书文件.crt如果只是为了开发测试也可以临时在Jenkins系统设置里跳过SSL验证但我不建议在生产环境这么干那等于把安全门拆了。8.2 插件报错500多半是版本兼容问题Jenkins最新版本在安装或升级插件时报500错误大概率是核心版本与插件版本不兼容或者插件与插件之间存在依赖冲突。排错时先看控制台日志或Jenkins系统日志搜索Exception关键字定位到具体是哪个插件抛出的异常再去插件官网查看该插件支持的最低Jenkins版本。有一种情况很混淆就是插件部分功能正常页面上一用就500。这种往往是插件和前端资源文件版本不匹配清理一下浏览器缓存或者换一个浏览器试一下有时候也能解决。8.3 构建环境与其他机器不一致同一个项目在本地mvn打包正常在Jenkins上却失败这类问题十有八九是环境差异。先确认Jenkins配置的JDK与Maven版本是否和本地一致再看本地settings.xml里配置的私服路径在Jenkins上是否也配置了最后看依赖缓存Jenkins首次构建要下载所有依赖网络不畅时的报错和代码本身毫无关系。8.4 环境变量到底从哪来有时候在Shell里明明设置了环境变量Pipeline里却拿不到。原因通常是Jenkins的agent节点和master节点环境隔离比如Docker agent里就是一套独立的环境。排查时可以在Pipeline里加一个步骤执行env命令把当前环境全部打出来看看你要的变量到底在不在、值是什么比瞎猜快得多。一点点自己的体会如果你问我现在回头去看Jenkins的一点点了解这个标题我会说其实Jenkins难的不是安装也不是某个具体配置而是对整个发布流程的理解从代码提交、自动构建、制品管理到部署上线、结果通知这是一条完整链路。Jenkins只是这条链路里一个非常称职的管事的人但它不会替你决定流程该怎么设计。所以我的建议是先手动把项目发一次版把每个步骤写下来然后尝试在Jenkins里逐步替换手工操作。一步能自动化的就先自动化一步暂时跑不通的保留人工操作也没关系。等你对Jenkins的环境变量、构建步骤、通知机制都越来越熟悉再回头优化为Pipeline一切都会顺理成章。最后分享一个我自己的小习惯每次改完Jenkins配置我都会在文本文件里记录一下改了哪里、为什么改、结果怎样。Jenkins的配置项实在太多有些设置半年不碰真的会忘。这份记录在排查问题、迁移环境的时候救了我无数次。
分享:

看完干货,该让你的企业上线了

免费需求沟通 · 48 小时内出具建站方案 · 河南本地可上门