ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

Jenkins插件安装与配置实战:在线离线、依赖与排错

Jenkins插件安装与配置实战:在线离线、依赖与排错 Jenkins 装完之后你会发现真正决定它能干什么的从来不是主程序本身而是你往里塞了哪些插件。默认安装包只给你一个能跑通“自由风格任务”的骨架想接 GitLab、想跑流水线、想把构建结果推到远程服务器、想在群里收到构建结果全都得靠插件安装和后续的配置把它拼出来。这篇使用教程不讲空理论就按我这些年从零搭环境、给团队做迁移、被插件依赖搞到半夜重启服务的实际过程把插件这套东西从“为什么装”到“怎么装”再到“装完怎么用、炸了怎么救”完整走一遍。刚接触 Jenkins 的新手可以照着抄已经用了一段时间但总被插件版本和离线安装折磨的同学也能在里面找到几处能直接省下几个小时排查时间的细节。1. Jenkins 插件体系到底是怎么回事1.1 核心加插件的设计逻辑决定了你必须学会装插件Jenkins 从早期版本开始就走的是“内核极小、能力外挂”的路线。官方主程序只保留了最基础的任务调度、构建触发、日志输出和一点点的 UI 框架像 Git 拉代码、Pipeline 语法解析、凭证加密存储、构建结果通知这些能力全部拆成了独立的插件包。这个设计的好处是内核能长期保持轻量坏处是你面对的环境千差万别官方不可能把所有人都需要的功能预设好于是“装插件”就成了每个 Jenkins 使用者的必修课。我在给团队做环境交接时最常说的一句话是Jenkins 的能力边界等于你装的插件集合。同一个版本的 Jenkins装没装 Pipeline 插件写出来的任务就是两种完全不同的东西装没装 GitLab 插件代码提交触发构建就得退回到轮询Poll SCM这种笨办法。理解了这一点你就不会再把插件当成“可选的美化项”而是把它当作搭建流水线的积木块来看待。还有一个容易被忽略的点插件是独立发布的。内核每年滚动几个版本插件的维护者可能是社区个人也可能是某家公司更新节奏完全不一致。这就带来了后面会反复提到的版本兼容问题——内核升级了、插件没跟上或者插件升级了、依赖的公共库没跟上都会导致 Jenkins 启动时报错甚至起不来。1.2 认清 .hpi 与 .jpi以及插件到底落在磁盘的哪里从插件管理器里下载下来的每一个插件本质都是一个后缀为.hpi的 Java 归档包里面放着编译好的类文件、前端资源、国际化的 properties 文件以及一个极其关键的MANIFEST.MF和pom元数据。当你手动上传一个.hpi文件时Jenkins 会把它复制到$JENKINS_HOME/plugins/目录下同时把文件名后缀改成.jpi。所以你在服务器上看到的git.jpi和你下载的git.hpi是同一个东西的不同阶段。弄清楚JENKINS_HOME的位置非常有必要它是所有排障的起点。在 Linux 上通常在/var/lib/jenkins或者你启动时用-DJENKINS_HOME指定的路径在 Windows 上用安装包装的一般在C:\ProgramData\Jenkins\.jenkins用容器跑的就是挂载出来的那个卷。我把常见目录的用途整理成一张表出问题时你按图索骥就行目录 / 文件作用出问题时怎么用plugins/所有已安装插件的.jpi文件和展开后的目录手动删掉某个插件目录即可卸载plugins/*.jpi.disabled被主动禁用的插件改名去掉.disabled即可恢复plugins/*.jpi.pinned被锁定版本的插件防止自动升级把它顶掉updates/更新中心元数据缓存元数据损坏时删掉重新拉取config.xml全局配置与已启用插件列表启动异常时可临时注释掉问题插件logs/各插件自己的日志输出插件静默失败时第一时间来看注意手动改plugins/目录之前一定先停 Jenkins 服务。热插拔文件在部分插件上会留下半加载状态表现为 UI 上能看到菜单点进去却报 500。1.3 装插件之前必须先确认的三件事第一件是内核版本。Jenkins 的插件页面会明确写出“需要 Jenkins X.Y 及以上”很多人图快直接下载最新版插件往老内核上怼结果启动时抛NoSuchMethodError。判断方法很简单登录后在右下角或者“系统信息”里看版本号再去更新中心确认。第二件是依赖链。Jenkins 插件之间是可以互相依赖的比如 GitLab 插件依赖 Git 插件和 Credentials 插件Pipeline 的withCredentials依赖 Credentials Binding 插件。在线安装时管理器会自动把依赖一起下下来但离线安装时它不会你得自己一个个补。这也是离线安装最常见的翻车点。第三件是升级站点是否可达。默认的更新中心地址在企业内网里经常拉不下来表现为插件列表一直是“正在加载”或者转圈几分钟后超时。这时候可以在“管理 Jenkins → 插件管理 → 高级”里更换成公开的镜像源或者干脆用内网自建的更新中心。这件事我在多个隔离环境里都踩过后面第 5 章会专门展开。2. 插件安装的四条路径与选型建议2.1 在线安装插件管理器是日常首选只要你的 Jenkins 能出网插件管理器就是最省事的方式。路径是“管理 Jenkins → 插件管理”进去后看“可选插件”页签搜索框里输入插件名勾选后点底部的“安装”或“下载并安装并在完成后重启”。这里有一个细节值得说“安装”和“下载并安装”是两个不同按钮。前者不会自动处理依赖升级后者会把依赖的一并装上代价是可能需要重启。日常我建议选后者多花两分钟少一堆莫名其妙的类缺失。安装过程中进度条会显示每个插件的状态这里的状态值很有信息量Pending排队还没轮到它通常是因为依赖没装完。Installing正在下载或解压。Success装好了但不代表已生效。Failed下载失败或版本不兼容日志里会有具体原因。Skipped被跳过了多是因为上级依赖失败。如果你看到一片Pending卡住不动九成是更新中心连不上别在那儿干等直接去看“高级”页签的站点地址。2.2 离线安装下载 .hpi 再上传注意依赖顺序隔离环境、生产环境不让出网就只能走离线安装。流程分三步先在能上网的机器上从插件索引页下载对应的.hpi然后在 Jenkins 的“插件管理 → 高级 → 上传插件”里选择文件最后等待上传完成后重启。这里我要强调一个几乎所有教程都不提的坑离线安装的顺序必须按依赖自底向上。举个我实际遇到的例子想把 GitLab 插件离线装到一台干净的内核上正确顺序是先装structs、credentials、git-client、git最后才装gitlab-plugin。如果顺序反了Jenkins 在上传时就会提示缺少依赖你只能一遍遍翻日志找还差哪个。我的做法是在联网环境的插件管理页面找到目标插件先按依赖关系把它拉成一份清单再按清单顺序下载。另一种更土但更可靠的做法是“整目录搬运”在一台已经配好插件的 Jenkins 上把plugins/目录和config.xml一起打包拷到目标机器上。这招适合做环境克隆但要注意两台机器的内核版本必须一致否则会因为序列化数据结构差异启动失败。2.3 命令行批量安装适合脚本化交付和 CI 镜像构建当你需要一次性装几十个插件或者在容器启动时自动补齐插件走 UI 就太慢了。Jenkins 提供的jenkins-cli.jar支持命令行安装# 从 Jenkins 主站下载 CLI版本要和控制端一致 curl -O http://jenkins.internal:8080/jnlpJars/jenkins-cli.jar # 通过 SSH 或 HTTP 方式执行安装命令 java -jar jenkins-cli.jar -s http://jenkins.internal:8080/ -auth admin:API_TOKEN \ install-plugin git gitlab-plugin workflow-aggregator docker-workflow -deploy-deploy参数表示安装完立刻部署不加的话只下载不生效。需要注意的是用命令行安装同样不会自动补依赖所以最好把依赖也一起写在命令里。我在一次交付里写了 40 多个插件名第一次跑失败了十几个后来把依赖全部列全才一次通过。2.4 容器化预装Docker 镜像里把插件固化下来用容器跑 Jenkins 的团队越来越多插件预装的最佳实践是构建自己的镜像而不是每次启动后手动装。官方镜像提供了install-plugins.sh新版本改名为jenkins-plugin-cli可以在构建阶段把插件写进镜像FROM jenkins/jenkins:lts-jdk17 # 新版镜像推荐用插件清单文件批量安装 COPY plugins.txt /usr/share/jenkins/ref/plugins.txt RUN jenkins-plugin-cli --plugin-file /usr/share/jenkins/ref/plugins.txt # 顺手加上国内的更新中心镜像加速后续的插件检索 COPY jenkins.mirror /usr/share/jenkins/ref/init.groovy.d/jenkins.mirror配套的plugins.txt写法很直白一行一个插件可以带版本号约束git:5.2.1 gitlab-plugin:1.7.14 workflow-aggregator:596.v8c21c963d92d docker-workflow:563.vd5d2e5c4007f credentials-binding:631.v861c06d062b3 dingding-notifications:2.4.3写版本号这件事我强烈建议养成习惯。不带版本号的清单今天构建一次、下个月再构建一次装出来的插件集合可能完全不同复现问题时会非常痛苦。2.5 重启、安全重启这两者别搞混装完插件通常需要让 Jenkins 重新加载类这里有两个选项重启 Jenkins直接停服务再启动正在执行的构建全部中断。安全重启Safe Restart等当前构建跑完再重启空闲后自动恢复。生产环境务必用安全重启。我曾经在一次紧急修复里手快点成了普通重启把一条正在做数据库变更的流水线砍在中间后面花了很大力气做数据回滚。这个教训值一条铁律任何插件变更都安排在构建低峰期。3. 高频插件清单与安装实操3.1 源码与流水线类插件先把地基打牢这一类是所有 Jenkins 环境的必装项缺了它们你根本做不了自动化。核心组合是Git 插件 Git Client Git Parameter Pipelineworkflow-aggregator。Git 插件负责和远端仓库通信Git Client 是它底层的 JGit 实现这两个是捆绑关系。Git Parameter 让你在触发构建时下拉选择分支或标签做多分支发版的团队几乎离不开它。Pipeline 插件是个“聚合包”装上它会一次性把workflow-job、workflow-cps、workflow-basic-steps、pipeline-stage-view等一整套拉进来这是我最推荐的做法——比一个个单装靠谱得多因为它内部维护了已知兼容的版本组合。实用心得如果你完全不用 Jenkinsfile只用自由风格任务那 Pipeline 那一整套可以不装能省下不少内存。但只要你打算用声明式流水线就必须装而且不要手动去改动它拉进来的子插件版本很容易把依赖树搞坏。3.2 触发与通知类插件让构建自己跑起来、结果自己送出去构建触发方面GitLab 插件是接 GitLab 代码托管平台的首选它同时提供了 Webhook 触发、构建结果回写Commit Status和“GitLab Connection”配置项。Generic Webhook Trigger是万金油任何能发 HTTP 请求的系统都能用它触发构建我甚至用它接过来自监控系统的告警。通知方面有几个组合值得说插件用途典型场景DingTalk钉钉通知向钉钉群机器人推送构建结果团队群内实时感知构建成败Email Extension可定制 HTML 邮件模板每日构建汇总、正式发布通知Build Failure Analyzer解析失败日志并给出原因统一归纳编译错误类型Slack Notification推送消息到 Slack海外团队协作钉钉插件这块我要多提一句很多人装了插件却在流水线里推不出消息问题九成出在消息格式和安全设置上。钉钉群机器人现在要求自定义关键词或加签插件里填的 Webhook 地址必须是完整的带access_token的地址并且机器人安全设置里要把 Jenkins 固定使用的关键词比如“构建”加进去否则消息会被直接拒掉。3.3 部署类插件把产物送到它该去的地方构建只是前半程后半程是部署。常用的有三个方向Publish Over SSH老牌但极其好用通过配置好的 SSH 服务器把文件 scp 过去并执行脚本。适合传统虚拟机部署。Docker Pipeline在流水线里直接调用docker build/docker push是容器化部署的基础。它依赖 Docker 插件和 Credentials Binding。Deploy to container把 war 包直接扔进 Tomcat 的 manager 接口做 Java Web 应用的自动部署时非常顺手。如果你的服务器在国内并且访问 Docker Hub 有困难配好daemon.json里的 registry mirror 是第一步否则流水线里docker pull会直接超时。这跟 Jenkins 本身无关但会表现为“Jenkins 插件装好了却跑不通”属于典型的误判来源排查时要有意识地把锅分清楚。3.4 一次完整的安装全过程记录我拿一台干净的 LTS 内核做演示把从零到打通 GitLab 触发的全过程走一遍。第一步确认版本与路径。在“管理 Jenkins → 系统信息”里记下内核版本比如2.440.3同时确认JENKINS_HOME。第二步更换更新中心。进入“插件管理 → 高级”把更新站点地址换成一个响应更快的源点“立即获取”让元数据刷新。刷新成功的标志是“可选插件”页签能正常列出上千条记录。第三步装核心包。搜索Pipeline勾选Pipeline这一项点“下载并安装并在完成后重启”。等它把一整套依赖拉完重启后检查“已安装”页签确认workflow-aggregator系列都在。第四步装 GitLab 相关。搜索GitLab勾选GitLab与GitLab Authentication如果你要用 GitLab 登录 Jenkins 的话同样选择带依赖安装。这里会顺带把 Git、Credentials 一并装上。第五步装通知与部署。按需勾选DingTalk、Publish Over SSH、Docker Pipeline。第六步验证。打开一个任务新建页面如果“构建触发器”里能看到Build when a change is pushed to GitLab源码管理里能看到Git说明插件已经生效。整个过程的日志建议留一份位置在$JENKINS_HOME/logs/。我有个习惯是把每次批量变更的插件清单记在项目的运维手册里下次换机器直接照着装能省掉全部试错。4. 插件配置实战从 GitLab 到自动部署4.1 配置 GitLab Connection让提交能触发构建装完 GitLab 插件只是第一步还需要建立连接。路径是“管理 Jenkins → 系统配置”拉到GitLab区域。需要填的字段有这么几个Connection name自己起名比如gitlab-prodGitLab host URL填你的代码平台地址Credentials需要选一个 GitLab API Token 类型的凭证。这个 Token 要在 GitLab 的个人设置里生成权限给api就够了不要用管理员 Token最小权限原则能省掉很多审计麻烦。配置完成后点Test Connection返回Success才算通。这一步失败通常有两类原因一是 Token 权限不足或已过期二是 Jenkins 服务器到代码平台的网络不通尤其是跨网段的场景一定要在服务器上用curl手动验证一次再回来排查 Jenkins。接下来在任务里勾选触发器Build when a change is pushed to GitLab页面会给出一个 Webhook URL 和一个 Secret Token。把这个 URL 填到 GitLab 项目的 Webhook 设置里勾上Push events测试一下能不能收到200响应。我见过最多的问题是把 URL 里的jenkins路径写错或者在内网地址前面加了https结果证书不匹配。4.2 Jenkins 可用环境变量流水线里最容易搞混的一块环境变量是插件和流水线之间的“公共语言”。很多插件装完之后你感觉没生效其实是没用对环境变量。下面这几个是我用得最频繁的变量名含义常见用途WORKSPACE当前构建的工作目录指定脚本执行路径BUILD_NUMBER本次构建的序号拼产物文件名、做版本后缀BUILD_URL构建详情页地址推送消息里附上链接JOB_NAME任务名称日志分类、消息标题GIT_COMMIT本次构建对应的提交哈希制品打标、回滚定位GIT_BRANCH/BRANCH_NAME分支名区分不同环境的部署策略JENKINS_URLJenkins 根地址拼回调地址NODE_NAME执行本次构建的节点名排查“在哪台机器上跑的”这里有个新手最容易踩的坑GIT_COMMIT这类变量在流水线里只有在checkout之后才可用。如果你在pipeline块的开头就引用它拿到的会是空字符串。正确做法是把它们放在stage(...)里、checkout scm之后使用。另外在environment块里写GIT_COMMIT env.GIT_COMMIT这种自引用是无效的因为那个时刻它还不存在。想查当前环境里到底有哪些变量最直接的办法是在流水线里插一段stage(打印环境变量) { steps { sh printenv | sort } }跑一次把输出存下来比你翻文档快得多。不过要注意输出里可能包含凭证日志对外可见时记得处理。4.3 自动部署 Java Web 应用把流水线串成闭环我把一段实际在用的流水线骨架贴出来业务是构建 Maven 工程并把 war 包推到远程 Tomcat。这里会用到 Git 插件、Maven 集成、Credentials Binding 和 Publish Over SSH 四个插件的组合。pipeline { agent any tools { maven maven-3.9 jdk jdk17 } environment { APP_NAME order-service DEPLOY_HOST deploy.internal } stages { stage(拉取代码) { steps { checkout scm sh echo 本次构建提交: ${GIT_COMMIT} 分支: ${GIT_BRANCH} } } stage(编译打包) { steps { sh mvn -B clean package -DskipTests archiveArtifacts artifacts: target/*.war, fingerprint: true } } stage(上传制品) { steps { sshPublisher( publishers: [ sshPublisherDesc( configName: deploy-server, transfers: [ sshTransfer( sourceFiles: target/*.war, removePrefix: target, remoteDirectory: /opt/tomcat/webapps, execCommand: systemctl restart tomcat-${APP_NAME} ) ] ) ] ) } } } post { failure { echo 构建失败检查上方日志定位编译或部署阶段 } } }几个关键点解释一下。tools块里的maven-3.9和jdk17需要在“全局工具配置”里预先配好插件装完不等于工具装完这是两个层面的东西。sshPublisher的configName对应系统配置里 Publish Over SSH 建的那条连接execCommand是文件传完后在远端执行的命令重启服务这种动作放在这里最合适。archiveArtifacts会把 war 包存进 Jenkins万一部署出问题还能回滚到上一版。参数选择上有个经验值removePrefix一定要写否则远端目录层级会被拉长成target/xxx.war这种结构容易覆盖错目录。execCommand里的服务名建议用变量拼别写死否则换环境要改流水线。4.4 钉钉自定义消息通知把构建结果送到群里钉钉插件的配置分两处。先在系统配置里启用DingTalk填好机器人 Webhook然后在任务的post块里调用。相比插件自带的简易配置我更推荐自己拼 JSON因为可定制程度高得多post { success { script { def payload { msgtype: markdown, markdown: { title: 构建成功, text: ### 构建成功\\n 任务${env.JOB_NAME}\\n 分支${env.BRANCH_NAME}\\n 序号#${env.BUILD_NUMBER}\\n [查看详情](${env.BUILD_URL}) } } dingTalk accessToken: dingtalk-token-id, imageUrl: , jenkinsUrl: env.JENKINS_URL, message: payload } } }有两点要注意。第一accessToken这里引用的是系统配置里那条钉钉配置的 ID不是机器人的 token 本身第一次配很容易填错。第二机器人如果开了加签插件里的密钥字段必须填否则推送会返回310000之类的错误码日志里只显示失败不显示原因得去钉钉后台看。5. 插件安装踩坑与排查速查5.1 常见报错与对应处理这一节几乎是这篇教程里最值钱的部分我把这些年遇到过的典型问题整理成速查表遇到时先照表判断再去看日志。现象可能原因处理方式可选插件列表一直加载中更新中心不可达更换更新站点地址或配置内网更新中心上传 hpi 后提示缺少依赖离线安装未按依赖顺序补装缺失的依赖插件后重传启动报NoSuchMethodError插件版本高于内核支持范围降级插件到兼容版本插件装上但菜单不出现未重启或加载失败安全重启后查logs/目录构建报docker: error response from daemon: get https://registry-1.d...镜像仓库不可达在 Docker 侧配置镜像加速地址钉钉通知发不出机器人关键词或加签未配核对 Webhook 与安全设置Webhook 触发无反应URL 或 Token 不匹配用curl手动打一次接口验证流水线里GIT_COMMIT为空在 checkout 前引用移到 checkout 之后使用5.2 版本冲突与降级回滚别硬扛版本冲突是插件体系里最折磨人的一类问题。典型表现是启动日志里刷出一长串Failed to load然后整个 Jenkins 卡在初始化页面。这时候千万不要连续重启试图碰运气正确的做法是停掉服务。去看$JENKINS_HOME/logs/下最新的一份日志找出报错的插件名。把plugins/里对应的目录和.jpi文件移到一个备份目录。重新启动确认能起来。再从检出问题的那个插件开始找一个兼容版本重新装。还有一种情况是自动升级把你坑了。Jenkins 默认会提示“有插件可更新”如果点了一键全升很容易出现依赖不匹配。我的习惯是把关键插件锁定在插件列表里把鼠标移到插件名旁边的图钉图标上点一下把它“钉住”这样自动检查更新时会跳过它。做法上就是给对应文件加.pinned后缀。注意生产环境升级插件前先做一次配置备份。把JENKINS_HOME下的config.xml、jobs/、plugins/复制一份出问题能快速还原。这比事后一点点回滚划算太多。5.3 内网隔离环境下的插件分发方案完全不出网的环境是很多公司的常态这时候前面讲的在线安装全部失效。我实践下来比较省事的方案是搭一个内部的插件分发点找一台能出网的机器做中转定期把常用的.hpi文件同步到一个内部文件服务器上Jenkins 通过“上传插件”从本地取文件。要做到这一步关键是提前准备一份标准插件清单让中转机器按清单批量下载避免每次现找。另一种方案是用更新中心代理的形式把 Jenkins 的更新中心地址指向内部某个静态目录服务把元数据 JSON 和 hpi 文件都放上去。这需要把updates/default.json和对应文件按目录结构摆放配置好之后使用体验和在线安装基本一致只是在离线环境里多了一次同步动作。5.4 我踩过之后总结的几条经验最后分享几个不太写在文档里但很有用的细节。第一插件不是越多越好。每装一个插件都会拉长启动时间、增加内存占用我接手过一个装了 180 多个插件的实例启动要六分钟。后来精简到 60 个左右启动不到一分钟而且依赖冲突明显变少。定期去“已安装”页签翻一遍把那些装了但根本没人用的清掉收益很直接。第二卸载插件要连着依赖一起看。有些插件你卸了它依赖的公共库还留着时间长了会堆出一堆孤儿插件。虽然通常无害但在排查冲突时会干扰判断。第三给插件相关的变更留出验证时间。装完之后不要立刻上生产流水线先拿一个测试任务跑一遍完整流程包括拉代码、构建、部署、通知四段全通了再切生产。我见过太多次“插件装完就发版结果通知没发出来”的尴尬。第四把插件清单当作代码来管理。不管是plugins.txt还是运维手册里的一张表版本号一定要落盘。半年后你要复现某个历史构建环境这份清单就是唯一的依据。我现在负责的几个环境都维护了这样一份清单每次变更都提交到版本库里出问题时对比 diff定位范围能缩到很小比对着日志瞎猜高效得多。
返回列表