ARTICLE DETAIL

资讯详情

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

放弃Jenkins:从脚本流水线迁移到图形化CI/CD平台的Kubernetes部署实践

放弃Jenkins:从脚本流水线迁移到图形化CI/CD平台的Kubernetes部署实践 做了快八年的运维和开发Jenkins是我最早接触的CI/CD工具也是让我心情最复杂的那个。团队规模小的时候一个自由风格任务加上几个Execute Shell就能跑通发布流程但到了项目多起来、部署目标变成Kubernetes集群之后Jenkins的每一项能力都需要插件和脚本去“凑”维护成本越来越高。去年我终于下决心换掉它换成的是一款完全图形化操作、免费开源、学习成本很低的CI/CD平台。这篇文章就完整记录下我为什么放弃Jenkins、怎么选型、以及迁移过程中的操作细节和踩坑经验。如果你是开发、测试或者运维同学正被Jenkins的Pipeline和插件版本问题折磨这篇应该对你有帮助。1. 先说痛点Jenkins到底卡在哪里先说清楚我不是为了否定Jenkins而写这篇文章。Jenkins作为老牌CI/CD工具在自动化构建、定时任务、复杂流水线这些场景里依然有它不可替代的价值尤其在大厂里有专门的DevOps团队维护能把它玩得很转。但问题是大多数团队没有专职的流水线工程师我们只是“顺便”兼着维护CI/CD的普通开发或运维。当Jenkins的维护成本开始超过它带来的便利时就该认真想想是不是要换条路了。1.1 从“插件全家桶”到“插件泥潭”Jenkins最吸引人的地方就是插件生态全球社区贡献了几千个插件从代码扫描、构建工具到各种部署插件几乎你能想到的它都有。但这也是最折磨人的地方。我刚接手的时候Jenkins里装了四十多个插件很多插件之间是隐式依赖关系你想升级A插件结果B插件不兼容一启动直接报错。曾经有一次Jenkins主节点挂掉我花了大半天排查最后发现是一个插件升级后和旧版API不兼容导致整个实例起不来。这种问题不是偶发而是周期性出现。每次Jenkins发大版本插件市场里就会有一批插件跟不上。团队的项目用的JDK版本、Maven版本、Docker版本都可能因为插件升级而被破坏。到了后面我养成了一个习惯升级之前先看插件依赖树再在测试环境验证一轮。但这已经偏离了CI/CD工具“让发布更省心”的初衷。维护Jenkins本身变成了一份全职工作。1.2 团队协作时的隐形门槛Jenkins还有一个容易被低估的问题它对普通团队成员非常不友好。自由风格任务还好说点点界面就能配置但只要涉及到稍微复杂一点的流水线就绕不开Groovy Pipeline。我记得第一次给后端团队写多分支流水线光整理分支合并、推送、部署的逻辑就写了一百多行Groovy脚本还要引入共享库给多个Job复用。写完之后运维的同事看着代码一脸懵测试的同事想自己往流水线里加一个冒烟测试步骤又不敢动我的脚本。这就导致一个很尴尬的局面CI/CD链路变成了“少数人手里的黑盒”。操作文档写了很多但团队里真正敢动Jenkins配置的始终只有一两个人。每次有人要发版都得通过消息来喊我“帮我跑一下这个Job”“这个参数应该怎么填”“又红了帮我看看日志”。工具本身是为了提效但当所有人都围着它转的时候效率反而被拖累了。1.3 几个真实让人崩溃的小场景我回忆了一下让我最终下决心换掉Jenkins的并不是某一个重大问题而是日积月累的“小伤小痛”。说几个有代表性的环境变量管理分散。Jenkins里的环境变量可以配置在系统设置、节点、Job、Pipeline脚本等多个位置真到排查问题的时候你根本不确定这个变量是从哪一层生效的。我们那时候出过一次事故QA环境部署用的镜像版本因为环境变量没覆盖到直接发布成了生产环境的版本虽然及时发现没造成太大影响但吓得所有人一身冷汗。容器环境里执行Docker命令麻烦。我们需要在构建节点里构建Docker镜像要么在宿主机上装一堆依赖要么用Docker in Docker处理起来都很折腾。Jenkins容器里挂载Docker Socket之后还要处理权限、挂载路径等问题每次换节点都要重新踩一遍坑。界面中英混杂。虽然Jenkins装了汉化插件但还有很多插件菜单、按钮、提示信息是英文的测试同事把截图发到群里问“这个单词是什么意思”已经成了常态。一个小问题就能打断节奏积少成多大家都在抱怨。Kubernetes配置繁琐。升级到2.541.3版本之后Kubernetes插件又要重新调整连接参数、Pod模板、凭证绑定光是配置文件就写了几百行。对比之下我只是想做到“构建完镜像之后更新一下Deployment”而已。这些场景单看都不是致命问题但叠加起来每天都要为此消耗不少时间和情绪。当我发现团队里每个人提到“发布”都在皱眉的时候我知道这个工具该换了。2. 选型思路什么样的CI/CD工具更适合现在的团队有了明确痛点之后我没有直接冲去找工具而是先把需求梳理清楚。工具选型最怕的就是“为了换而换”如果没有清晰的标准换完大概率还会踩同样的坑。下面分享一下我当时定下的选型标准和判断逻辑。2.1 我定下的五条选型标准在对比了市面上多款CI/CD工具之后我把自己的需求浓缩成五条。这些标准我们团队也讨论过最后一致认可免费开源或者社区版对中小团队足够用。我们团队规模不大预算有限付费工具虽然专业但人均成本算下来不划算。完全图形化操作核心流程不依赖写代码。这里的“图形化”不是指能画个流水线图而是从项目配置、构建步骤到部署动作全部能在界面上完成不用写Groovy、不用写YAML。学习成本低团队普通成员能快速上手。我希望测试同学也能自己触发构建、查看结果、定位失败步骤而不是每次都找运维。对Docker和Kubernetes支持友好。我们现在大部分服务已经容器化构建镜像和部署K8s是刚需工具必须在这两个方面有开箱即用的能力。部署维护轻量不占太多服务器资源。小团队没有专职运维工具本身最好安装简单、运行稳定别让我像伺候Jenkins一样伺候它。2.2 为什么“完全图形化”是我最看重的一点很多人会觉得图形化的灵活性不如代码配置这个观点对但有前提。大型团队、复杂发布策略、多环境多集群的海量流水线确实需要配置即代码来管理版本和审计。但对大多数中小团队来说流水线往往就是“拉代码-构建-测试-部署-通知”这条主链路复杂度远没有到非要脚本定义不可的程度。我更看重的是“让每个环节可见”。图形化操作带来的最大好处不是省写代码的时间而是降低协作成本。拿我们团队举例以前测试妹子和我说“构建那步挂了”我得去Jenkins里翻日志现在图形化界面里一条流水线摆在那哪个节点红了、卡了多久、日志在哪一眼就看出来她自己也敢点进去看细节。工具越直观团队的自主性就越强这才是真正的提效。我自己也承认在“深度自定义”这个维度上图形化工具和脚本化工具还是有差距。但我们的核心需求是稳定、可见、好维护而不是搞一套极其复杂的灰度发布矩阵。想清楚这一点图形化方案就成了我们的最优解。2.3 我最终选定的方案与直观对比多方比较后我落地选用的是国产开源CI/CD平台“建木CI”核心原因是它完全覆盖了上面五条标准免费开源界面原生中文整个流程像搭积木一样通过图形化编排节点完成对Docker和Kubernetes有内置支持服务端部署也轻量。当然同类产品还有不少选型思路是相通的。把Jenkins和建木CI放在一起做了一次直观对比结论很清晰对比项Jenkins建木CI新工具配置方式自由风格任务Groovy Pipeline脚本图形化拖拽/节点连线编排学习成本高需要理解插件、凭证、脚本概念低普通开发/测试人员可直接上手界面语言原生英文汉化插件覆盖不全原生中文插件机制强依赖插件生态版本冲突频发内置常用能力少量扩展按需启用资源占用高JVM实例大量插件轻量容器化部署分钟级安装Docker/K8s支持需插件脚本配置原生节点图形化配置构建和部署我也在内部做过一次小范围投票让前端、后端、测试同事分别试用一小时结果一致倾向新工具。这个反馈让我更确信选型不是选“技术最强大的”而是选“团队用得最顺的”。3. 新工具的核心能力拆解与实操要点工具选定了接下来就是上手。这里我会把建木CI的几个核心能力拆出来结合我们日常真实的配置过程讲一下你在用其他同类图形化CI/CD工具时大概率也能对应得上。3.1 图形化编排从“写流水线”到“搭积木”建木CI最核心的体验就是可视化编排。项目空间里新建一条流水线你会看到一张画布左侧是各种可拖拽的节点包括“代码拉取”“命令执行”“Docker构建”“Docker推送”“Kubernetes部署”“消息通知”等。你只需要把节点拖到画布上通过连线把它们串起来再每个节点点进去填参数一条流水线就出来了全程不写一行脚本。我们后端Java服务发布这条流水线当时配置成了这样代码拉取节点填Git仓库地址和分支内置了凭证选择。命令执行节点执行mvn clean package把构建产物准备好。命令执行节点执行docker build -t registry.xxx.com/app-server:v1.2.3 .构建镜像。Docker推送节点填镜像仓库地址、账号、密码或Token把镜像推上去。Kubernetes部署节点填Kubeconfig文件、命名空间、Deployment名称、镜像地址和版本。消息通知节点填webhook地址发送构建结果到群。整个配置过程大概花了半小时。最直观的感受是不用再记那些Groovy语法了每个节点的参数项都在界面上列了出来填错格式保存时就会提示。对没有编程基础的测试同事来说也能轻松看懂整个流程的先后关系。3.2 环境变量、命令执行与日志把“看不见的坑”搬到界面上之前被Jenkins环境变量问题坑过之后我在选型时特别关注了这一点。建木CI把环境变量分成了几个层级全局变量、项目变量、流水线变量在界面里分别管理作用域一目了然。我在全局变量里配了镜像仓库地址、通知Webhook这类全局通用的信息在项目变量里配了每个服务独立的命名空间和分支名。流水线运行时变量会按层级自动注入不会出现“变量到底从哪里来”的困惑。命令执行节点就是图形化外壳下的“自由脚本”你可以填任意Shell命令。日志这一块体验差得不是一点半点Jenkins日志大部分是纯文本流排查问题要在里面翻很久建木CI的日志按节点单独展示可以边跑边看实时输出还支持关键字搜索哪个节点执行了什么命令、输出是什么、退出码是多少全部独立归档。定位一次构建失败点开红色节点就能看到错误日志特别省时间。一个很实用的细节在命令执行节点里写多行Shell脚本时建木CI支持像文本编辑器一样的编辑体验还有常用的Shell命令模板可以插入比如“切换目录”“设置环境变量”“安装依赖”。就算不熟悉Shell的人也能照着模板拼出一条可用的构建命令。3.3 容器与Kubernetes部署支持不再被插件牵着走说实话最让我惊喜的是新工具对Docker和Kubernetes的原生支持。之前用Jenkins的时候要在流水线里构建镜像往往得写一段Groovy脚本调用Docker插件还要处理节点上的Docker权限问题要部署到K8s就得再引入Kubernetes插件配置一堆连接参数。建木CI把这两个能力内置成了节点填参数就能用。具体操作上我配置Docker构建节点时只要选好Dockerfile所在的上下文目录、填镜像名称和标签即可。底层它会调用节点上已安装的Docker或者通过挂载Docker Socket执行构建。这里有个安全建议如果不想给节点过大的权限可以选择专用的构建容器来执行Docker构建避免直接暴露宿主机Docker Socket。我们初期图省事挂载了Socket后来安全审查不通过改成了构建容器模式配置成本增加的不多但安全等级提升了好几个级别。Kubernetes部署节点就更直观了。节点里可以选集群配置文件也就是Kubeconfig、命名空间然后填Deployment名称和要更新的镜像Tag。执行时它本质上是在帮你执行kubectl set image deployment/xxx xxx镜像地址:Tag但你完全不用关心命令是怎么写的。对于像我们这样每天只发布两三次服务的小团队来说这种“傻瓜式”的部署体验远比一套复杂的发布系统更实用。3.4 触发方式与自动化部署闭环图形化工具不等于全是手动触发。建木CI支持多种自动触发方式我们实际用下来最常用的是这三种Git Webhook触发代码推送到指定分支后自动触发构建和部署。这个是我们现在的主流程开发只要合并代码到主干发布流水线就自动跑起来。定时触发可以配置每天的固定时间执行一次流水线非常适合做每日夜间构建、生成测试报告这类周期性任务。手动触发界面上点“运行”按钮还可以在运行时临时填写一些参数值适合测试同事在发版前手动拉起预发环境部署。这三种方式组合起来基本覆盖了日常所有发布场景。而且触发记录在界面里都能查到每次运行是谁触发的、用的什么参数、结果如何全都有迹可循。4. 从Jenkins迁到新工具的完整过程如果你也想把Jenkins换掉最担心的往往是“切换过程会不会出问题”。这里我把自己实际的迁移过程拆解一遍包括怎么盘点资产、怎么分步切换、怎么保证随时能回滚。4.1 迁移前先盘点Jenkins里的“全部家当”不要一上来就在新工具里建项目先花点时间把Jenkins里的存量资产梳理清楚。我当时的做法是打开Jenkins管理界面把每一个Job都点进去看一遍然后整理成一张清单。重点记录四类信息构建步骤里到底执行了哪些命令尤其是那些带着一堆环境变量和参数的命令务必逐个确认。项目里配置了哪些环境变量、凭证比如Git仓库密码、镜像仓库Token、服务器SSH密钥这些迁移后要重建。每个Job是手动触发、定时触发、还是Webhook触发触发源是哪个仓库的哪个分支。部署目标是哪台服务器、哪个K8s集群、哪个命名空间部署方式是执行脚本还是kubectl命令。盘点的过程很枯燥但绝对不能省。我见过有人迁移CI/CD时不盘点以为新工具建个流水线就行结果迁移后发版才发现某个Job里藏了一个互动数据库的备份命令差点搞出生产事故。用表格把这四类信息列清楚后面每一步都会顺手很多。4.2 三步迁移法先试跑、再核心、后全量我实际迁移用了大概一周时间分成了三个阶段。不要追求一口气全量切换风险太大。第一步先挑一个非核心项目试跑。我选的是一个内部管理系统的前端项目改动不频繁、影响面小。在这个项目上把新工具的整个链路跑通创建项目、配置Git仓库、编排构建部署节点、触发一次完整发布。这一步主要验证工具本身能力以及团队对操作方式的接受度。第二步迁移核心项目。把后端Java服务、用户端小程序这些核心项目按照盘点的结果逐一迁移到新工具。注意这一步不是“照抄”旧流程而是借机优化。比如以前的Pipeline里有几个废弃的构建步骤迁移的时候直接去掉了以前环境变量分散在多个位置这次全部收拢到新工具的项目变量里统一管理。第三步切换Webhook触发流量。等所有核心项目迁移完毕再把Git仓库的Webhook地址从Jenkins切到新工具。因为Jenkins还在运行这时候两边是可以并行的。我们会先观察几天确认新工具跑的构建结果和Jenkins一致再让团队正式停用Jenkins。4.3 切换过程中的回滚策略与注意事项很多人在迁移的时候容易忽略回滚方案。我的经验是Jenkins实例不要急着销毁保留它但设为“只读/暂停触发”状态保留至少两到三周。这样万一新工具出现某些极端情况比如某个插件兼容问题或者编排逻辑理解有误我们随时可以把Webhook切回Jenkins按老流程发布保证业务不受影响。我在切换时遇到过一个小插曲新工具跑前端项目时Node模块安装失败排查下来是构建节点上的Node版本和Jenkins节点不一致。这时候因为Jenkins还在运行团队先按老流程顶了一阵我慢慢调整新节点的Node版本等构建恢复稳定后才继续切换。如果没有保留回滚路径线上发布就会被卡住。这个经验值得记录下来。5. 高频问题与避坑实录工具再好用实际跑起来总会遇到问题。这里把我在迁移和日常使用中遇到的典型问题整理成一个速查表再补充几个实战细节算是给大家的“避坑包”。5.1 常见问题速查表问题现象可能原因解决方案流水线里环境变量取不到值变量配置层级不对被上层/下层覆盖在“流水线变量”最底层优先级最高注意区分全局、项目、流水线三层作用域Docker构建报Permission denied构建节点没有Docker权限或未挂载Socket把执行用户加入docker组或配置专用构建容器并正确挂载DockerWebhook触发不生效仓库Webhook地址填错或者分支匹配规则不对检查仓库后台的Webhook配置和流水线里的触发分支条件Kubernetes部署步骤超时Kubeconfig文件权限问题或集群网络不通先在该节点手动执行kubectl命令验证连通性再回界面上重试镜像构建缓存经常失效上下文目录过大Dockerfile分层不合理调整.dockerignore精简构建上下文尽量把依赖安装步骤放在Dockerfile靠前位置通知消息没发出去Webhook地址失效或网关限制了出口访问在通知节点里先测试发送确认能收到后正式接入这个表格里的问题大多是我自己踩过的坑。现在回头看90%的问题都不是工具有Bug而是基础环境配置或者使用习惯没有调整过来。遇到问题先看节点日志再顺着环境配置排查基本都能解决。5.2 几个值得记住的实战细节最后分享几个我实际用下来的小经验。第一个是关于敏感信息的处理。无论用哪个CI/CD工具都不要把密码、Token、Kubeconfig直接写在命令里或者流水线的参数里。建木CI里有专门的凭证管理功能可以把密钥存起来在节点配置时下拉选择引用。这样做的好处是就算流水线日志打得很详细真正的密码也不会暴露在日志中。第二个是关于通知节点。我们一开始总是把通知放到流水线最后如果前面某个节点失败就不发通知了。后来我调整成两个通知节点一个放在失败出口专门发“失败失败节点日志链接”另一个放成功出口发“构建成功镜像地址”。这样团队收到的消息永远是有针对性的信息而不是笼统的“构建未成功”。第三个是关于流程设计。不要在一个流水线里堆太多无关紧要的步骤。以前用Jenkins的时候为了省事会在一套流程里同时做格式化检查、单测、代码扫描、镜像构建、多环境部署。结果就是一次失败全部从头再来浪费大量时间。现在我会把“静态检查”和“发布部署”拆成两条流水线一条主流程只跑构建和测试一条发布流程在确认代码健康后单独执行部署。这样职责清晰失败的影响面也小。整个迁移过程走完后我的体会是工具切换不是换一套技术栈那么简单本质上是改变团队的工作习惯和协作方式。Jenkins陪我们走过了好几年在自动化建设初期帮了大忙但当它开始成为团队的负担时果断换掉才是最正确的选择。如果你也在纠结要不要放弃Jenkins我的建议是先找一个非核心项目试水完整跑一遍构建、部署、通知的闭环让团队成员亲身体验一下“图形化操作”带来的不同再决定也不迟。
返回列表