耿雷 赵宏翔 李建友 张华鹏 王铁一
摘要:提出了一种基于Jenkins实现一键式快速部署的系统方案,介绍了Jenkins,Docker,Git以及Nexus Repository Manager关键技术及其特征,通过这些关键技术的集成,阐述了一键式部署方案的流程和系统架构设计,并以操作系统CentOS7为例,详细介绍了系统方案的环境搭建以及具体实现,包括Dockerfile和Jenkinsfile的编写。通过构建Jenkins流水线任务,在项目开发过程中需要重新打包部署时,开发人员能够一键式快速完成项目上线。
关键词:Jenkins;一键式部署;Docker
中图分类号:TP393文献标志码:A文章编号:1008-1739(2022)24-50-5
随着计算机技术的愈发成熟,软件项目的復杂度也越来越高,传统的瀑布式开发模式开发周期长、阶段固化,无法适应当今形势的发展。此外,随着信息化时代的飞速发展,如今的商业环境发生了翻天覆地的变化,人们每天接收到各种各样的信息,对软件的需求变化也越来越快,需求本身具备不确定性,不是一次性或者一段时间就可以完全定义清楚的,传统的瀑布模型无法在开发过程中不断根据需求变化动态地调整产品。整个商业环境日新月异,迫使企业更快地做出决策,更快地推出新产品到市场中去,因此,敏捷开发成为了市面上企业开发模式的主流趋势[1]。
敏捷开发是一种迭代式开发,在需求的不断变更中,软件需要频繁进行部署,一个团队里有多个开发人员,每个人在开发完各自新功能后可能都要访问服务器进行部署,每个人的部署方式各异,这就会导致每次部署的软件配置不统一,并且还浪费开发人员的时间精力。即使有专门的运维人员负责软件迭代部署,每次部署的工作量也是比较大的。因此,本文提出了一种基于Jenkins流水线的一键式部署方案,并通过实践,给出了设计方案的实现流程。
1.1 Jenkins
目前,企业软件的开发流程主要分为:编码、构建、集成、测试、交付和部署6个阶段,在这个流程中,持续集成(Continuous Integration,CI)、持续交付(Continuous Delivery, CD)和持续部署(Continuous Delivery,CD)都具有不同的自动化交付周期。
持续集成是指频繁地将代码整合到主分支中。把软件单独开发的一部分交给整体软件,经常进行持续集成,这样可以更迅速地找到bug。持续集成有2大优势:①能够迅速地找到bug。每次完成一小部分更新,都会被整合到主分支中,这样能够迅速地找到bug,并且易于查找错误。②避免其他分支明显地从主分支上脱离。如果没有频繁地整合,并且主分支还在不断地升级,那么日后的整合将会非常困难,甚至很难进行整合。持续集成的目标是在保证高品质的前提下,使产品能够迅速地进行迭代。其关键的一点是,在将代码整合到主分支之前,必须经过自动测试。如果其中一个测试案例是失败的,那么将无法继续进行。
持续交付是指经常向用户或质量队伍提供新版本的软件,以便进行审核,如果审核被批准,则该代码将被投入到产品中。持续的交付是基于持续的整合,在实际的运行环境中(贴近生产环境)部署整合后的代码。持续交付是基于高度自动化的持续集成基础上的软件部署,在整个产品生命周期中,它的优先级是最高的。可将持续交付视为持续整合的下一个步骤,其关键核心是,无论软件怎么升级,无论何时何地,都能提供该软件的交付版本。
持续部署是接下来的一个阶段,即在经过审核之后,软件会被自动地部署到生产环境中。持续部署的目的是使软件处于随时都能部署的状态,并能投入到生产中。持续部署的先决条件是测试、构建、部署等步骤自动化。
总体而言,持续集成、持续交付和持续部署提供了一个非常好的DevOps环境。它可以极大地提高整个开发团队的开发效率,同时也带来了挑战。在任何情况下,频繁部署、快速交付和自动化的测试过程将是未来软件工程中的关键环节。
Jenkins是一个持续的集成工具,它是在Java开发基础上能够进行持续的软件发行和持续的测试。Jenkins可以轻松地进行配置,从而使开发人员摆脱复杂的集成,将精力集中在更加关键的商业逻辑实施上。Jenkins具有以下特性:
①开源的Java语言开发持续集成工具,支持CI和CD;
②丰富的插件支持:支持插件的扩展,可以根据自己的小组需求,开发例如Docker,svn,maven,Git等工具;
③文件识别:Jenkins可以追踪jar包是在哪次构建产生的,使用的jar包的版本是什么等;
④安装部署简便:支持多种方式安装部署,可以在yum上安装,或者下载war软件,或者通过Docker容器来进行安装;支持在Web界面进行管理配置;
⑤支持分布式构建:Jenkins可以支持多个电脑共同进行构建和测试。
本文将使用Jenkins的流水线来构建部署项目,使得整个部署过程流程化。Jenkins流水线的定义被写入到一个名为Jenkinsfile的文本文件中,每次构建时Jenkins会根据Jenkinsfile定义好的流水线语句自动执行任务,为本文一键式部署提供了很好的自动化、流程化工具。
1.2 Docker
Docker[2]是一个开源的应用容器引擎,让开发者可以将他们的软件和依赖打包生成一个镜像,然后在Docker启动发布到服务器上。Docker将部署的项目容器化,在Docker环境中,简化了对容器的复制、启动、关闭和删除,使得部署的操作更加简捷;Docker具有更好的兼容性和移植性,除了内核之外,它提供了一个完整的运行时环境,保证了执行环境的一致性,用户可以很轻易地将一个平台上运行的应用迁移到另一个平台上,无需考虑操作系统和运行环境影响。
Docker是利用谷歌公司发布的Go语言来开发完成的,它使用了Linux内核的cgroup和namespace等技术,将进程封装隔离起来,这是一种在操作系统级别上的虚拟化技术。因为被隔离的进程是与寄主或其他隔离进程无关的,所以也被称为“容器”。Docker是以容器为基础,对其进行了再一次的包装,从文件系统到网络连接,再到进程隔离,大大简化了创建和维护容器的流程,使Docker技术相比于虚拟机技术更加轻快、便捷。Docker作为一种新的虚拟技术,它相比传统的虚拟化方法有很多优点:
①更有效地使用系统的资源
Docker可以更好地利用系统资源,因为它无需硬件虚拟和运行整个操作系统。相比于传统的虚拟机技术,Docker文件存储速度、应用程序的执行速度和内存消耗都要快得多。所以,与虚拟机技术相比,同一配置的主机,Docker可以执行更多的应用程序。
②更快地启动
传统的虚拟机技术通常要花费几分钟才能启动一个应用程序,但是Docker容器程序可以在几秒、甚至毫秒级内完成,因为它是在主机核心上运行的,不需要操作系统完整启动,这极大地节省了开发、测试和部署的时间。
③拥有统一的运行环境
在软件开发中,一个普遍存在的问题是环境的一致性。由于开发环境、测试环境和生产环境的不统一,可能造成一些bug以及在开发阶段没有被测试出来的问题。Docker的镜像除了提供了一个完整的运行时环境,还保证了应用程序运行环境的一致性,这样就不会有“开发没问题,部署跑不通”的问题了。
④支持持续交付和持续部署
对于开发和操作(DevOps)的人而言,最需要的是在完成了一次创建或者配置后,能够在任何地点都能正常工作,即“一次配置,到处运行”。使用Docker可以通过自定义应用镜像,完成持续集成、持续交付和持续部署。开发者可以结合Dockerfile来创建镜像,而且可以与持续集成系统协同来完成集成测试;运维人员可以将这个镜像迅速地部署到生产环境中,甚至可以与持续集成工具整合完成自动快速部署。同时,通过Dockerfile来实现镜像构建,不仅开发团队能够了解应用程序的运行环境,还可以让维护团队了解应用程序的部署条件,从而更好地部把镜像部署到生产环境中。
⑤拥有更快捷的移植性
因为Docker保证了运行环境的一致性,所以可以很轻松地进行移植。Docker支持在众多平台上运行,不管是虚拟机、物理机、私有云、公有云甚至笔记本,都能得到相同的运行结果。这样,用户就可以轻松地将一个应用程序移植到另外一个平台,而不必担心由于运行环境的改变而使程序不能正常工作。
⑥易于维护和扩展
Docker采用了分层存储和镜像技术,可以方便重用应用程序中的重复部件,同时也可以简化程序的维护和升级,并且可以轻松地通过基本镜像来进一步扩展镜像。同时,Docker团队和不同的开放源码项目小组共同维护了大量高品质的官方镜像,这些镜像可以直接用于产品中,也可以作为基础进行进一步的镜像定制,从而大大减少了应用程序的镜像制作成本。
1.3 Git
Git是一款小巧靈活却功能强大的分布式版本控制系统,相比于集中式版本控制系统,Git在每个开发者的计算机本地拥有一套完整的代码仓库,开发者可以把代码提交到本地仓库,然后将这些代码发送到远程仓库,或者将最新的代码提取出来,与本地的仓库进行合并。Git更加强调个体,拥有良好的分支机制,能够减轻公共服务器仓库压力。本文使用Git进行项目统一管理,部署所需的软件包和文本文档均来自于项目的Git远程仓库[3]。
1.4 Nexus Repository Manager
Nexus Repository Manager是一款强大的仓库管理软件,它大大简化了对内部仓库的维护和对外部仓库的存取,经常被用作Maven的私有仓库,也可以作为Docker,npm和yum等的私有仓库,功能强大。本文使用Nexus作为Docker镜像文件的私有仓库,对镜像文件统一管理,可以存储Docker基础镜像文件或者已经打好包的镜像文件,用户可以从Nexus仓库拉取基础镜像构建新镜像,也可以拉取已经做好的镜像直接在本地Docker中启动。
一键式部署的目标就是当软件版本发生变更需要重新部署时,开发人员无需关注部署的各种繁杂细节,只需要将软件打好包上传到项目远程仓库,在Jenkins中使用一键构建,系统即可自动生成项目的Docker镜像,将镜像文件推送至远程Nexus私有Docker仓库,然后启动运行容器。自动部署完成后即可访问部署的新版本软件。一键式部署方案流程如图1所示。
整个工作流程涉及开发人员计算机、持续集成服务Jenkins、项目远程仓库服务、私有仓库管理服务Nexus以及Docker服务。一键式部署方案架构如图2所示。其中,开发人员计算机使用Git客户端工具从项目远程仓库中拉取项目最新代码,将修改好的代码和打包好的项目文件推送到项目远程仓库服务;Jenkins服务使用Git插件从项目远程仓库中拉取项目文件夹,执行Jenkinsfile脚本文件,从Nexus Docker镜像仓库拉取基础镜像构建目标镜像文件,将构建好的镜像推送至Nexus Docker镜像仓库,启动容器时再从镜像仓库中拉取镜像执行启动命令[4]。
3.2.1 Dockerfile
Dockerfile是一个文本文件,用于构建自定义镜像。在Dockerfile中首先需要声明制定构建新的镜像文件所使用的基础镜像,以部署jar包为例,基础镜像使用的是openjdk,ip: port处输入访问Nexus的地址和端口;然后需要为RUN,CMD,ADD和ENTRYPOINT等指令设定工作目录,将要部署的jar包文件添加到容器中并重命名为app.jar;把项目用到的端口暴露给外界;设置镜像的时区以保证时间正确;使用RUN构建镜像,使用ENTRYPOINT配置容器,使其可执行化。Dockerfile文件具体内容如下:
FROM ip:port/ amd64/ openjdk:8u312
WORKDIR /tmp
ADD demo-2.3.5. RELEASE.jar app.jar
EXPOSE 8000 8010
ENV TZ=Asia/ Shanghai
RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime ENTRYPOINT ["java","-jar","app.jar"] 3.2.2 Jenkinsfile
Jenkins流水线的定义被写在一个名为Jenkinsfile的shel1脚本文件中,因此,需要定义好一个流水线,使整个部署流程自动化。流水线具体操作分为以下4个步骤:
①File Check文件检查。首先检查构建镜像所需的文件正确齐全,例如jar包、Dockerfile等。
②Docker Build构建镜像。首先,使用docker rm命令,移除旧版本容器以及移除旧版镜像,包括Nexus仓库的镜像,这一步是为了防止镜像冗余导致不用的镜像占用空间;接着,通过docker build -t demo:1.0 .命令构建新镜像,1.0表示版本号,后续更新版本可以进行相应的修改。
③Docker Push推送镜像。这一步是将上一步生成好的镜像文件推送至Nexus远程私有仓库。先登录Nexus私有仓库(docker login),使用docker tag标记本地镜像,将其归入Nexus仓库,然后使用docker push将其推送至Nexus仓库。
④Docker Run运行容器。最后一步运行容器,使用docker run命令,通过指定镜像文件、设置文件映射、端口映射和容器名称等信息启动容器。
本文分析了当前开发模式的现状,在敏捷开发环境下项目需要频繁部署,因为使用传统的部署方式会大大占用开发人员的时间和精力,所有本文提出了一种基于Jenkins服务进行一键式部署项目的解决方案,整个方案架构以Docker为基础环境,通过整合Git,Jenkins和Nexus实现了便捷的一键式部署,大大节省了部署所需耗费的人力和物力。目前,本文的一键式部署方案已经过验证投入到实际应用中,实现了项目的快速持续集成,提高了整个团队的项目开发效率。
[1]程宁,戴远泉.基于Jenkins持续集成部署研究与实现[J].电子制作,2021(22):46-48.
[2]张延冬,邢艳芳.基于Docker的运维平台设计[J].计算机时代,2018(4):16-18.
[3]石庆冬.版本管理工具Git的主要特点[J].电子技术与软件工程,2022(7):72-75.
[4]贾灶生.基于Jenkins的云原生应用的持续集成設计和实现[D].西安:西安电子科技大学,2021.
[5]林美蓉. CentOS 8上Docker部署FTP服务器的两种方式[J].网络安全和信息化,2022(10):67-69.
[6]陈子通,马迎新,关梅茹.基于Jenkins平台的ECU软件持续集成系统搭建[C]// 2020中国汽车工程学会年会.上海:机械工业出版社,2020:70-79.
[7]胡志宝.基于Jenkins技术实现自动测试系统研究[D].北京:华北电力大学(北京),2021.