分享吧初探Docker在持续集成中的作用
Posted 大连飞创
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了分享吧初探Docker在持续集成中的作用相关的知识,希望对你有一定的参考价值。
一
引言
随着软件开发复杂度的不断提高,开发团队与运维团队如何更好地协同工作以确保软件开发的质量已经慢慢成为开发过程中不可回避的问题。如何能在不断变化的需求中快速适应和保证软件质量也显得尤其重要。
二
持续集成概述
持续集成正是针对这类问题的一种软件开发实践。持续集成(Continuous Integration,简称CI)作为先进的项目实践之一,近年来逐渐受到国内软件公司的重视。大师Martin Fowler对持续集成是这样定义的:持续集成是一种软件开发实践,即团队开发成员经常集成他们的工作,通常每个成员每天至少集成一次,也就意味着每天可能会发生多次集成。每次集成都通过自动化的构建(包括编译,发布,自动化测试)来验证,从而尽快地发现集成错误。
过去的几年甚至更长的时间中,软件开发团队己经从原本的瀑布式开发,转变为敏捷开发方法。虽然瀑布模型多年来一直是很多复杂系统的开发标准,但是也有几个明显的缺陷。比如需求的变化不能及时得到满足,只有在项目的后期才能进行集成测试而无法及时发现问题,项目不同阶段之间的独立性而带来的各种文档工作,极大地增加了工作量。而在敏捷开发中,快速迭代、快速反馈的特点,当项目因为用户各种原因而不断改变需求时,能够最大限度地保证开发效率。但是当项目随着规模的扩大而复杂度提高时,由于其被拆分成很多不同的子模块,集成工作往往也同时变得很复杂。为了保证各个子模块在不断向前推进时,还需要能够保证他们在一起整合时可以正常工作,持续的集成测试也变得相当重要。在软件开发期间持续不断地进行集成测试,能够及时发现一些项目上存在的质量问题。如果不能及时发现,往往在后期这些问题会给项目带来很大的风险,会导致项目的延迟,甚至会导致项目失败。
2.1国内外研究现状
持续集成最早源于敏捷开发的极限编程(XP),它是XP最初的12种实践之一。2000年,ThoughtWorks公司的Martin Fowler发表了一篇题为《Continuous Integration(持续集成)》的文章,文章中他将持续集成定义为一种软件开发实践。这种软件开发实践的主要过程为:在一个项目开发过程中会进行大量的集成,这些集成工作由项目中每个成员来进行,并且要求是很频繁的。通常情况下,在每次集成时将通过对项目的自动化的构建及测试,来保证此次集成的有效性,以暴露出其中存在的问题,从而可以开发出高品质的软件产品。这篇文章发表之后,持续集成逐渐开始流行,其价值被更多的开发者及软件公司所发现和认可,并逐步应用到实际的项目中。持续集成作为敏捷开发流程中的一个重要组成部分,它对开发团队的代码进行集成、构建、测试等等,使得开发团队无需将大量的时间浪费在对代码集成的问题上,大大提高了开发的效率。
国外的软件公司对持续集成的研究相对国内较早。当大师Martin Fowler加入 ThoughtWorks公司时,他便鼓励公司的团队使用该技术,同时也开发出一款特别的工具CruiseControl来部署持续集成环境,以帮助团队更方便地来完成持续集成工作。CruiseControl本身也是一款开源工具,它在很大程度上推进了早期持续集成的发展。
Sun公司在2005年开发并发布了开源的Hudson工具,很快便超越了 CruiseControl,从此Hudson便成为了最流行的持续集成工具。自从Oracle收购了Sun公司之后,希望将Hudson作为收费的商业软件来开发,但Hudson社区的核心开发人员则决定继续免费版本的开发,从此Jenkins便登上了历史舞台。发展至今,Jenkins己经成为了目前市面上最流行的持续集成工具,它不但能友好地支持各种语言的项目构建(如Java, C#, php等),还能兼容Ant, Maven等多种第三方构建工具,同时可以与SVN, Git等版本管理工具集成工作。另外Jenkins还提供了方便的可视化web页面,不管是在系统的搭建、配置,还是后期的测试、维护上都很便捷,受到了广大开发者的喜爱。
在国内,虽然软件行业起步较晚且在持续集成方面也有落后,但是随着近年来互联网行业的飞速发展,越来越多的软件公司开始重视持续集成这一实践。比如百度公司,从2009年引入敏捷开发。在公司产品规模不断扩大的时候,研发效率的重要性也愈发凸显出来,因此也进一步采用了持续集成系统来提供服务,并在2010年将其应用到了各个产品线。同时百度也在不断地更新、完善整个持续集成系统,建立起了全自动化的测试、部署及交付流程,对整个项目开发的效率都起到了很大的提高作用,并在软件产品的质量上也得到了更大的保证。
2.2构成要素
要构成一个有效的持续集成系统,需要有相应的软硬件服务的配合,其中各个模块之间的配合工作也是很重要的。下面简要介绍一下构成持续集成系统的几大要素。
1) 统一的中心代码库
一个软件项目往往需要多名开发人员共同协作,为了避免工作的混乱,一款比较优秀的版本管理系统是很重要的。通过版本管理系统,我们在项目中可以维护一个比较统一的中心代码库,一方面可以让每个开发者都很容易获取项目的最近代码,并将自己的修改往中心代码库提交,另外一方面持续集成系统进行构建时,也是从该中心代码库中获得最新的代码进行的。同时当我们需要追溯一个比较久远的问题时,基于一个版本管理系统的中心代码库也可以很容易checkout出往日的版本来供调试。
目前市面上有很多优秀的版本管理工具,比较流行的有集中式的CVS、Subversion 以及分布式的TortoiseHg、Git等,而近几年来,由于Git灵活、快速的特点,以及其对分支管理的便捷,越来越多的开发团队将其应用到软件项目中去。
2) 构建自动化
将中心版本库中的代码变成一个正式的软件产品往往需要一系列繁杂的流程,最常见的是需要将代码检出、编译、链接、配置等等,而这一系列的过程在一个持续集成系统中将会是完全自动化的过程。因为一旦中间某个步骤需要人工去操作,该系统便失去了其独特的魅力,也不能称之为一个持续集成的系统了。
通常的构建过程是由具体的项目决定的,不同的项目也许会基于不同的开发语言,需要不同的开发环境,另外或许还需有不同的配置要求,所以我们要根据实际的开发项目来完成一个可供其他脚本调用的构建脚本,这样我们在将一个新的项目引入到持续集成系统时,仅仅需要关心该项目本身的构建过程,而不需要每次都来维护持续集成系统与各项目之间的协作关系。
3) 测试自动化
一般意义上的构建仅仅是将软件代码通过编译、链接、配置等过程,生成一个可以运行的软件系统,但这不是我们采用一个持续集成系统的主要目的。一个开发人员,他不仅仅需要知道自己提交的修改是否能够编译通过,还希望能知道自己的修改是否带来一些bug。基于这种情况,一个有效的持续集成系统在自动化的构建后,仍需要完成自动化的测试工作。将一个高效的自动化测试包含到持续集成系统中,通过对代码的大范围的覆盖,我们可以用一系列的测试代码来将代码中可能存在的问题最大限度地找出来,避免后续更多的繁琐工作。
4) 模拟生产环境下的测试
测试的主要工作是找出项目中可能存在的问题,而这些问题中最重要的是在生产环境下暴露出来的。如果不能够跟生产环境保持一致,那么再多的测试工作也无法发现在生产环境中将暴露的问题。所以在持续集成系统中,我们需要在没有人工干预的情况下,做到每次的测试条件都尽可能与生产条件一样,可以最大限度的模拟出在真实运行情况下可能出现的问题。但现实情况往往是由于环境的限制,我们并不能完全模拟真实的生产环境,尤其比较糟糕的是在多次构建之间,后面的构建会因为前一次构建对环境产生不可清除的影响而导致失效或无法检验出全部bug。因此每次构建前的搭建一个干净的环境也是比较重要的,后文中提到的Docker技术的采用,就是为了达到这一目的。
5) 获悉系统状态
持续集成的目的在于反馈,需要保证所有的开发人员能清除看到目前持续集成系统的当前状态。比如当我提交了一次修改,需要知道大概多久后可以获得系统反馈,此时我便需要去查看当前系统状况,构建是否己经开始,是否正常工作,运行到了哪一步,或者也可以通过查看历史构建情况来预估本次构建所需时间。所以一个比较好的持续集成系统需要提供一个窗口来向开发人员展现系统本身的状态,比如著名的持续集成工具Jenkins,便是通过一个web系统来提供系统配置服务以及系统状态的展示。
6) 自动化部署
引入一个自动部署工具,无论是对于本地开发者,还是对于项目的版本管理维护人员,可以避免日常频繁的重复部署工作,这将促进软件的总体效率的提高。在整个项目包括测试与部署的周期中,使用一些有效的工具来替代人力的干预,不但可以节省等待人力完成工作的时间,而且在过程中去掉了人力干预,可以使得软件质量变得更加可预测,会变得更好,另外客户也能很迅速体验到新的功能。所以作为持续集成的一项基本原则,自动化部署比较有利地完成这样的一些工作。
三
Docker概述
3.1Docker简介
Docker是一个分布式应用构建、迁移和运行的开放平台,它允许开发或运维人员将应用及其运行依赖的文件打包至一个标准化容器运行。将Docker引入持续集成发布系统,可实现快速部署和通过镜像共享工程环境功能,使得开发、测试和运维能够实现环境复用和一键化部署。在虚拟化技术方面,虚拟机是把底层设备资源进行虚拟化,而基于Docker的容器技术是直接建立在Linux系统内核之上的,是通过系统内部的进程将资源进行虚拟隔离的,因此容器技术在系统性能上远比虚拟机消耗的少。
在Docker服务中,容器是组成服务的核心内容,相对于虚拟机,它在性能上更加高效。有人指出“在容器内部架构中,对容器整个生命周期的维护是通过libcontainer技术来实现的,该技术还用于容器的信息管理以及信息传输管理。容器以镜像为模板,创建一个独立的且资源隔离的运行环境”。也有人指出“容器是一种运行状态,是镜像运行时的环境,而镜像是静态的,当镜像从静态变成动态,便成为了容器。用户在容器内部可以运行自己所开发的代码程序,作为容器来说,它并不了解内部具体运行的程序或者是服务,所有程序服务在其内部的运行都是一致的,其操作包括创建、启动、重启和关闭;用户可以在各种平台中运行容器,不论是物理服务器中还是虚拟机,都可以运行容器”。容器对于技术来说,不是一个新的概念,但是Docker在对容器技术进行封装后,使容器技术更加易于交互、易于移植、易于扩展,使传统的软件开发过程中的流程形态发生了改变,使得部门间的资源协调更加高效。
镜像的文件在服务器中是只读的状态,它的内部为容器运行的环境配置,当配置按照顺序执行完毕后,容器便开始运行。Docker的另一个创新是对层级镜像的应用,即不同的容器可以共同使用来自底层的只读镜像,容器通过写入自己每次更新的内容后,新的镜像层便会附加到只读镜像上,新增加的镜像层和下一层镜像又可以一起作为基础镜像被更上层的镜像使用。这种特性可以极大的提高硬件磁盘的利用率,当系统上有10个1GB的镜像时,它们总共占用的空间可能只有5GB,甚至会更少。另外Docker对Union mount的应用还体现在多个容器使用同一个基础镜像时,可极大的减少内存使用,因为不同的容器访问同一个文件时,只会占用一份内存。
Docker镜像库是用来存储用户上传的镜像文件,并对上传过程进行相应的记录。每个镜像库都是用户的一个存放目录,用户可以建立多个目录来存放自己上传的镜像文件。所有的镜像库组成一个镜像存储服务器。该服务器有给普通用户使用的,也有给只属于组织内部使用的。其中给普通用户使用的例如官方的Docker Hub,在该平台中,所有人都可以注册自己的账号,并在自己建立的库中上传自己的镜像。镜像库可以选择开放或者私有,多数企业会选择自己部署注册服务器后进行二次开发。
3.2Docker优势
当Docker引入持续集成构建系统时,一切发生了革命性变化。由于 Docker具有快速部署和通过镜像共享工程环境的功能,使得开发、测试和运维团队能够复用工程环境,从而形成开发、测试和运维一键部署的基础。目前,国内外已有很多公司发布了基于Docker容器技术的开发、测试和运维一站式解决方案。同时,与Docker相关的编排管理工具(如 Kubernetes等)也在不断完善,使得Docker在测试领域得到广泛应用。Docker实现持续集成的主要优势如下:
1) 开发、测试和生产环境的统一化和标准化:镜像作为标准交付件,可在开发、测试和生产环境中以容器运行,最终实现3套环境中的应用及其运行依赖内容的完全一致。
2) 解决底层基础环境的异构问题:不同的物理设备、虚拟化或云计算平台,只要是运行了Docker Engine的环境,最终应用均会以容器为基础提供服务。
3) 易于构建、迁移和部署:Dockerfile实现镜像构建的标准化和可复用,镜像本身的分层机制也提高了镜像构建效率。使用容器仓库(Registry)可将构建好的镜像迁移至任意环境,而且环境部署仅需将静态只读的镜像转换为动态可运行的容器即可。
4) 轻量和高效:与需封装操作系统的虚拟机相比,容器仅需封装应用及其依赖文件即可实现轻量的应用运行环境,且拥有比虚拟机更高的硬件资源利用率。
5) 工具链的标准化和快速部署:多种工具或软件进行 Docker化后,可在任意环境实现1条或多条工具链的快速部署。
通过Docker提供的虚拟化方式,可快速建立一套可复用的开发环境,以镜像形式将开发环境分发给所有开发人员,达到简化开发环境搭建过程的目的。Docker以镜像和在镜像基础上构建的容器为基础,以容器为开发、测试和发布单元,所有与该应用相关的依赖均在容器里封装,移植方便,避免了应用在不同平台间迁移带来的依赖性问题,确保了应用在生产环境各阶段达到高度一致的实际效果。
四
持续集成过程
如图所示首先项目的开发人员需要在本地更新一份中心代码库的最新代码,然后根据需求进行代码修改,完成功能开发。确认无误后再将修改提交到Git中心代码库。Git服务器通过webhook通知Jenkins有更新。此时,Jenkins从Git上下拉最新代码通过maven进行编译构建,然后通过Dockerfile构建镜像,Push镜像到镜像仓库。最后,删除当前容器,重新运行新版本镜像。
Docker作为最后程序运行的容器,其主要优势在于使用Docker打包应用程序,其使用者不用在其程序运行时所依赖的环境配置中花费太多的时间,并与Docker集群编排系统进行配合使用,更加方便程序运行时的横向扩展。
参 考 文 献
[1] 张成.基于Docker的持续集成系统的设计与实现[D].苏州大学,2016.
[2] 丁海斌,崔隽,陆凯.基于Docker的DevOps系统的设计与实现[J].指挥信息系统与技术,2017,8(3):87-92.
[3] 华为Docker实践小组.Docker进阶与实战[M].北京:机械工业出版社,2016.
[4] 曾金龙,肖新华,刘清.Docker开发实践[M].北京:人民邮电出版社,2015.
以上是关于分享吧初探Docker在持续集成中的作用的主要内容,如果未能解决你的问题,请参考以下文章
转简易的微服务持续集成方案,SpringBoot+Docker+Jenkins+Gitlab
持续集成:docker下使用jenkins容器构建docker镜像