前言
容器时代到来之后,代码自动化部署从纸上谈兵跃迁到生产实践,jira,禅道等为代表的项目需求管理工具,gitlab为代表的代码版本管理工具,传统的jenkins自动化任务工具,新兴的gitlabCI ,jenkinsX等云上自动化任务应用工具为代表的的自动化发布核心流程工具,docker,k8s ,helm 层级逐渐递增的容器部署及容器编排部署工具,配合周边的一些持久化工具,质量检查工具,自动化测试工具,甚至是OA审批流,整合了需求把控,代码管理,自动化发布及相关内容。
谈谈git flow
什么是git flow
git flow版本管理流程,可以满足绝大部分企业的代码管理规范流程,git分布式代码管理工具成为企业代码版本工具的标准之后,小到几人的微服务开发者,大到数百人的单体巨应用的开发者,都是用git作为版本管理工具,人越多,就需要制定标准,git flow就是结合git强大的分支管理提出的一个标准或者规范。
git flow解决了什么问题
- 由于很容易去创建分支,分支多了如何管理,这么多的分支都是做什么的?
- 如何开始一个需求分支,而不影响其他需求分支的正常开发过程?
- 哪些分支已经合并到了主分支,哪些分支应该废弃掉?
- 发布分支如何管理? 开始一个release分支的时候如何冻结feature分支,如何在prepare release的时候,不影响开发人员在feature继续开发?
- 线上出现了紧急bug,如何快速修复,并且修复的问题要包含到开发人员的分支以及下一个relase分支中?
现状
大部分的应用,项目使用git作为版本管理,只是用两个甚至三个分支,Master线上分支,develop主开发分支,然后就是一个乱七八糟的各种命名的分支,这种情况,在小产品,小团队,小项目中还可以支撑,一旦规模起来之后,那将是灾难性的。
git flow的分支
在git flow分支分类一般是五类,分别是
- Production 分支
也就是我们经常使用的Master分支,这个分支最近发布到生产环境的代码,最近发布的Release, 这个分支只能从其他分支合并,不能在这个分支做任何的修改。
- Develop 分支
这个分支是我们是我们的主开发分支,包含所有要发布到下一个Release的代码,这个主要合并与其他分支,比如Feature分支。
- Feature 分支
这个分支主要是用来开发一个新的功能,一旦开发完成,我们合并回Develop分支进入下一个Release。
- Release分支
当你需要一个发布一个新Release的时候,我们基于Develop分支创建一个Release分支,完成Release后,我们合并到Master和Develop分支。
- Hotfix分支
当我们在Production发现新的Bug时候,我们需要创建一个Hotfix, 完成Hotfix后,我们合并回Master和Develop分支,所以Hotfix的改动会进入下一个Release。
流程描述
梳理一下一个产品从开发到上线再到二版本上线的整个过程
- 主程序员(产品开发负责人)创建本地和远端仓库,初始分支为master,此分支作为线上分支,不允许做任何的直接改动。
- 基于master检出develop分支,作为开发主分支,开始分配开发人员权限,并运行开发环境,配合测试人员测试。
- 分配需求,不同的需求创建不同的feature分支,要求这些需求开发最大化隔离,不要互相依赖,在开发基于develop创建新的feature分支的时候,提交向develop的merge request,任何问题和代码沟通都可以在merge request中和主程序员沟通。
- feature开发完成,要求开发人员自测联调通过,并联系主程序员 review merge request,主程序员决定是否可以接受本次merge request,接受同意merge 关闭merge request。
- 基于dev分支提供开发测试环境,提供系统集成开发测试,测试人员测试功能。
- 上线负责人(一般也是主程序员或者开发经理),基于develop检出relase分支,准备上线,在切出之前合并到develop的需求作为本次上线内容,部署到预生产环境,提交测试,一期测试人员介入,二期业务人员介入。
- 在release测试的任何问题,都基于relase分支切出hotfixs分支进行紧急修复,修复完成之后,合并回relase分支,主程序员要判断本次修改是否会影响到feature,如何有影响,则develop要合并release分支内容,并同步给开发人员,再合并到feature继续开发,如果无影响,并且所有的测试问题修复,则开始准备上线内容,最后修改应用版本为v1.0,并在版本页面或者数据库记录本次发版内容,relase分支打tag 比如v1.0,merge 到master分支上,作为本次上线内容。merge回develop分支,同步relase的修改,本次release分支一直停留到下次relase发布前。
- 基于master分支打出本次上线内容程序包(目前一般都是镜像),部署生产环境,开放业务使用。
- 在master上使用出现了紧急bug,基于relase分支切出新的hotfixs分支进行紧急修复,修复完成,合并到release分支,在预生产环境交给测试和业务确认之后,提交线上修复审批,同意之后,修改小版本号,比如v1.0.01版本,在版本页或者数据库记录本次发版内容,同步到master分支,发版。
- 开发人员完成新的上线需求,主开发人员同意merge请求,处理完上个release分支的事务,提出新的release分支,开始测试,同样要经历bug修复等等。
- 测试,业务测试通过之后,主程序员修改版本号和记录本次版本迭代内容,打tag,记录本次版本,比如v1.1,合并到master和develop分支,master制作新的程序发布包(镜像),滚动升级,灰度发布,逐渐扩大新版本覆盖策略。
谈谈应用版本号
- 使用语义版本命名的软件系统必须定义一套公共API。这套API可以是在代码中申明或是用严格的文档定义。不管怎样做,它都应该清楚明了。
- 正常的版本号必须使用X.Y.Z的形式并且(X/Y/Z)是非负整数。X是主版本号,Y是次版本号,Z是补丁版本号。 版本号每次必须只能增长1。例如:1.9.0->1.10.0->1.11.0。
- 当主版本号增长时,次版本号和补丁版本号必须清零。当次版本号增长时,补丁版本号必须清零。例如:1.1.9->2.0.0,2.1.7->2.2.0。
- 一旦发布了具有版本的包,那个版本的内容必须不能再更改。任何修改必须发布成一个新版本。
- 主版本号0 (0.y.z)是用来进行初始开发时使用的。任何东西都可能在任何时候改变。公共API此时应该被认为是经常变动的。
- 版本1.0.0开始定义公共API。这个版本及以后的版本号的增长方式将依赖于公共API以及它如何变化。
- 如果单一子产品有任何向下兼容的bug修复发生,补丁版本号Z (x.y.Z )必须增长1,“bug修复”被定义为内部进行的修复非正常行为的修复工作
- 如果单一子产品进行了新的并且向下兼容的公共API添加、优化、修改,次版本号Y (x.Y.z )必须增长1,如果任何公共API被标记为“过期”,次版本号必须增长1,如果有大量的新功能或改进在内部代码中发生,次版本号可以增长1,这其中也可以包含补丁级别的修改,当次版本号增长时补丁版本号必须清零
- 如果单一子产品对公共API有任何向下不兼容的修改,或者两个及两个以上子产品同时发布新特性,或者主产品开辟新业务模式,主版本号X (X.y.z)必须增长1,这其中也可以包含次版本和补丁版本级别的修改,当主版本号增长时次版本号和补丁版本号必须清零
谈谈自动化发布
自动化发布要分为两块来讲,自动化一块,发布一块,先聊聊发布这个过程
发布
当源码测试通过,发布流程审批通过之后,这个应用就应该要发布了,发布要做哪些事情呢?
- 源码管理按照git flow规范去走,具体参考上文谈谈 git flow
- 发布版本严格按照版本规范去走,具体参考谈谈应用版本号策略
- 发布流程严格按照公司内部规定,比如,发布需要流程申请,通过审批之后发布
- 发布前严格测试数据库脚本,脚本需要制作正逆两个,发布使用正向脚本,版本回退使用逆向发布,如果是不可回退发布,则需要停服,备库。
- 发布前对新增的配置信息严格测试,例如发布配置清单内容,切不可丢失配置信息。
- 尽可能的使用滚动升级,保证服务对外无损。
- 发布成功之后,访问应用的版本页,内容是否符合本次发布内容。
- 发布成功之后,调用自动化接口测试,相关功能是否符合预期,没有自动化接口的话,则需要人为验证是否通过。
- 切换流量,灰度流量切换比例,将部分流量切换过来使用新的功能,待稳定之后,逐渐切换全部流量过来。
自动化
自动化是一个程序员喜闻乐见的事情,任何重复的工作,不管是谁,都不希望自己反复的去做,持续集成构建部署都是一个重复性达到百分之九十的工作,为什么是百分之九十,因为还有一部分工作需要人为是做,比如,修改发布信息,审批是否可以发布,备份数据库,人工check list,灰度比例等,这些建议还是有个负责人去把控一下,其他的内容,比如 源码编译,生成制品,制作镜像,推送镜像,生成编排文件,生成helm包,自动化测试,滚动升级,这些步骤不管发布多少次都是一模一样的,那么就建议这些步骤全部自动化去做,人为都不要干预了。
自动化工具选型
- jenkins
- jenkins是一款优秀的开源CI&CD软件领导者, 提供超过1000个插件来支持构建、部署、自动化, 满足任何项目的需要,但是因为目前容器比较火,jenkins的策略又是映射到本地的工具去做一些事情,比如maven,npm,yarn编译类的工具,所以,在此之上,如果原来使用的jenkins,建议考虑jenkinsX工具来作为自动化工具。
- gitlab CI
- GitLab CI 是GitLab内置的进行持续集成的工具,只需要在仓库根目录下创建.gitlab-ci.yml 文件,并配置GitLab Runner;每次提交的时候,gitlab将自动识别到.gitlab-ci.yml文件,并且使用Gitlab Runner执行该脚本。
- 两者对比
- jenkins的脚本使用的groovy语法,需要学习语法和内置的函数方法,gitlab CI使用的是yarm文件,对开发者优化,步骤定义简单。
- jenkins插件生态太丰富,几乎可以完成所有想完成的功能,gitlabCI 起步不久,生态没有那么丰富,但是正常的CI&CD需求可以覆盖满足。
- jenkins与gitlab 仓库解耦,gitllabCI 虽然调度的是runner,但是页面和仓库页面在一起。
- 客户端执行效率,jenkins的slave可以运行在k8s中,理论上支持N多任务同时执行。
自动化步骤应该有哪些
- 需求bug等管理工具,参考工具jira,禅道等
- 源码管理工具 gitlab 差不多是行业标准了
- 代码质量检测 sonar 很棒的java代码检查工具,可以个性化定制检查项
- 编译工具,maven ,gradle(java),npm yarn (node)等等
- 单元测试
- 制品 (maven,gradle,npm,yarn,docker,tar,zip等)
- 仓库 (jar包仓库,镜像仓库,helm应用仓库等)
- 部署 (docker,k8s,helm) 目前helm使用的趋势在逐渐上升。
- 自动化测试,jmeter等
参考资料链接
- k8s中文社区: https://www.kubernetes.org.cn/
- jenkins官网: https://jenkins.io/zh/
- jenkinsX 官网: https://jenkins.io/zh/projects/jenkins-x/
- jenkinsX 平台: https://github.com/jenkins-x/jenkins-x-platform
- docker官网: https://www.docker.com/
- dockerhub站点: https://hub.docker.com/
- gitlabCI说明: https://docs.gitlab.com/ee/ci/
- 搭建gitlabCI: https://about.gitlab.com/product/continuous-integration/
- sonar质量检查: https://www.sonarqube.org/
- helm说明: https://helm.sh/
- 前端构建神器 : https://yarn.bootcss.com/
- 开源对象存储: https://docs.min.io/cn/
- 接口自动化测试 jmeter : https://jmeter.apache.org/
- git教程: https://www.liaoxuefeng.com/wiki/896043488029600