聊聊从代码管理到自动化发布

2020/01/19 CICD

前言

​ 容器时代到来之后,代码自动化部署从纸上谈兵跃迁到生产实践,jira,禅道等为代表的项目需求管理工具,gitlab为代表的代码版本管理工具,传统的jenkins自动化任务工具,新兴的gitlabCI ,jenkinsX等云上自动化任务应用工具为代表的的自动化发布核心流程工具,docker,k8s ,helm 层级逐渐递增的容器部署及容器编排部署工具,配合周边的一些持久化工具,质量检查工具,自动化测试工具,甚至是OA审批流,整合了需求把控,代码管理,自动化发布及相关内容。

谈谈git flow

什么是git flow

​ git flow版本管理流程,可以满足绝大部分企业的代码管理规范流程,git分布式代码管理工具成为企业代码版本工具的标准之后,小到几人的微服务开发者,大到数百人的单体巨应用的开发者,都是用git作为版本管理工具,人越多,就需要制定标准,git flow就是结合git强大的分支管理提出的一个标准或者规范。

​ git flow解决了什么问题

  1. 由于很容易去创建分支,分支多了如何管理,这么多的分支都是做什么的?
  2. 如何开始一个需求分支,而不影响其他需求分支的正常开发过程?
  3. 哪些分支已经合并到了主分支,哪些分支应该废弃掉?
  4. 发布分支如何管理? 开始一个release分支的时候如何冻结feature分支,如何在prepare release的时候,不影响开发人员在feature继续开发?
  5. 线上出现了紧急bug,如何快速修复,并且修复的问题要包含到开发人员的分支以及下一个relase分支中?

​ 现状

​ 大部分的应用,项目使用git作为版本管理,只是用两个甚至三个分支,Master线上分支,develop主开发分支,然后就是一个乱七八糟的各种命名的分支,这种情况,在小产品,小团队,小项目中还可以支撑,一旦规模起来之后,那将是灾难性的。

git flow的分支

https://github.com/superhxf/superhxf.github.io/blob/master/_posts/images/o_git-flow-nvie.jpg?raw=true

​ 在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。

流程描述

梳理一下一个产品从开发到上线再到二版本上线的整个过程

  1. 主程序员(产品开发负责人)创建本地和远端仓库,初始分支为master,此分支作为线上分支,不允许做任何的直接改动。
  2. 基于master检出develop分支,作为开发主分支,开始分配开发人员权限,并运行开发环境,配合测试人员测试。
  3. 分配需求,不同的需求创建不同的feature分支,要求这些需求开发最大化隔离,不要互相依赖,在开发基于develop创建新的feature分支的时候,提交向develop的merge request,任何问题和代码沟通都可以在merge request中和主程序员沟通。
  4. feature开发完成,要求开发人员自测联调通过,并联系主程序员 review merge request,主程序员决定是否可以接受本次merge request,接受同意merge 关闭merge request。
  5. 基于dev分支提供开发测试环境,提供系统集成开发测试,测试人员测试功能。
  6. 上线负责人(一般也是主程序员或者开发经理),基于develop检出relase分支,准备上线,在切出之前合并到develop的需求作为本次上线内容,部署到预生产环境,提交测试,一期测试人员介入,二期业务人员介入。
  7. 在release测试的任何问题,都基于relase分支切出hotfixs分支进行紧急修复,修复完成之后,合并回relase分支,主程序员要判断本次修改是否会影响到feature,如何有影响,则develop要合并release分支内容,并同步给开发人员,再合并到feature继续开发,如果无影响,并且所有的测试问题修复,则开始准备上线内容,最后修改应用版本为v1.0,并在版本页面或者数据库记录本次发版内容,relase分支打tag 比如v1.0,merge 到master分支上,作为本次上线内容。merge回develop分支,同步relase的修改,本次release分支一直停留到下次relase发布前。
  8. 基于master分支打出本次上线内容程序包(目前一般都是镜像),部署生产环境,开放业务使用。
  9. 在master上使用出现了紧急bug,基于relase分支切出新的hotfixs分支进行紧急修复,修复完成,合并到release分支,在预生产环境交给测试和业务确认之后,提交线上修复审批,同意之后,修改小版本号,比如v1.0.01版本,在版本页或者数据库记录本次发版内容,同步到master分支,发版。
  10. 开发人员完成新的上线需求,主开发人员同意merge请求,处理完上个release分支的事务,提出新的release分支,开始测试,同样要经历bug修复等等。
  11. 测试,业务测试通过之后,主程序员修改版本号和记录本次版本迭代内容,打tag,记录本次版本,比如v1.1,合并到master和develop分支,master制作新的程序发布包(镜像),滚动升级,灰度发布,逐渐扩大新版本覆盖策略。

谈谈应用版本号

  1. ​ 使用语义版本命名的软件系统必须定义一套公共API。这套API可以是在代码中申明或是用严格的文档定义。不管怎样做,它都应该清楚明了。
  2. 正常的版本号必须使用X.Y.Z的形式并且(X/Y/Z)是非负整数。X是主版本号,Y是次版本号,Z是补丁版本号。 版本号每次必须只能增长1。例如:1.9.0->1.10.0->1.11.0。
  3. 当主版本号增长时,次版本号和补丁版本号必须清零。当次版本号增长时,补丁版本号必须清零。例如:1.1.9->2.0.0,2.1.7->2.2.0。
  4. 一旦发布了具有版本的包,那个版本的内容必须不能再更改。任何修改必须发布成一个新版本。
  5. 主版本号0 (0.y.z)是用来进行初始开发时使用的。任何东西都可能在任何时候改变。公共API此时应该被认为是经常变动的。
  6. 版本1.0.0开始定义公共API。这个版本及以后的版本号的增长方式将依赖于公共API以及它如何变化。
  7. 如果单一子产品有任何向下兼容的bug修复发生,补丁版本号Z (x.y.Z )必须增长1,“bug修复”被定义为内部进行的修复非正常行为的修复工作
  8. 如果单一子产品进行了新的并且向下兼容的公共API添加、优化、修改,次版本号Y (x.Y.z )必须增长1,如果任何公共API被标记为“过期”,次版本号必须增长1,如果有大量的新功能或改进在内部代码中发生,次版本号可以增长1,这其中也可以包含补丁级别的修改,当次版本号增长时补丁版本号必须清零
  9. 如果单一子产品对公共API有任何向下不兼容的修改,或者两个及两个以上子产品同时发布新特性,或者主产品开辟新业务模式,主版本号X (X.y.z)必须增长1,这其中也可以包含次版本和补丁版本级别的修改,当主版本号增长时次版本号和补丁版本号必须清零

谈谈自动化发布

自动化发布要分为两块来讲,自动化一块,发布一块,先聊聊发布这个过程

发布

​ 当源码测试通过,发布流程审批通过之后,这个应用就应该要发布了,发布要做哪些事情呢?

  1. 源码管理按照git flow规范去走,具体参考上文谈谈 git flow
  2. 发布版本严格按照版本规范去走,具体参考谈谈应用版本号策略
  3. 发布流程严格按照公司内部规定,比如,发布需要流程申请,通过审批之后发布
  4. 发布前严格测试数据库脚本,脚本需要制作正逆两个,发布使用正向脚本,版本回退使用逆向发布,如果是不可回退发布,则需要停服,备库。
  5. 发布前对新增的配置信息严格测试,例如发布配置清单内容,切不可丢失配置信息。
  6. 尽可能的使用滚动升级,保证服务对外无损。
  7. 发布成功之后,访问应用的版本页,内容是否符合本次发布内容。
  8. 发布成功之后,调用自动化接口测试,相关功能是否符合预期,没有自动化接口的话,则需要人为验证是否通过。
  9. 切换流量,灰度流量切换比例,将部分流量切换过来使用新的功能,待稳定之后,逐渐切换全部流量过来。

自动化

​ 自动化是一个程序员喜闻乐见的事情,任何重复的工作,不管是谁,都不希望自己反复的去做,持续集成构建部署都是一个重复性达到百分之九十的工作,为什么是百分之九十,因为还有一部分工作需要人为是做,比如,修改发布信息,审批是否可以发布,备份数据库,人工check list,灰度比例等,这些建议还是有个负责人去把控一下,其他的内容,比如 源码编译,生成制品,制作镜像,推送镜像,生成编排文件,生成helm包,自动化测试,滚动升级,这些步骤不管发布多少次都是一模一样的,那么就建议这些步骤全部自动化去做,人为都不要干预了。

自动化工具选型

  1. ​ jenkins
    1. jenkins是一款优秀的开源CI&CD软件领导者, 提供超过1000个插件来支持构建、部署、自动化, 满足任何项目的需要,但是因为目前容器比较火,jenkins的策略又是映射到本地的工具去做一些事情,比如maven,npm,yarn编译类的工具,所以,在此之上,如果原来使用的jenkins,建议考虑jenkinsX工具来作为自动化工具。
  2. gitlab CI
    1. GitLab CI 是GitLab内置的进行持续集成的工具,只需要在仓库根目录下创建.gitlab-ci.yml 文件,并配置GitLab Runner;每次提交的时候,gitlab将自动识别到.gitlab-ci.yml文件,并且使用Gitlab Runner执行该脚本。
  3. 两者对比
    1. jenkins的脚本使用的groovy语法,需要学习语法和内置的函数方法,gitlab CI使用的是yarm文件,对开发者优化,步骤定义简单。
    2. jenkins插件生态太丰富,几乎可以完成所有想完成的功能,gitlabCI 起步不久,生态没有那么丰富,但是正常的CI&CD需求可以覆盖满足。
    3. jenkins与gitlab 仓库解耦,gitllabCI 虽然调度的是runner,但是页面和仓库页面在一起。
    4. 客户端执行效率,jenkins的slave可以运行在k8s中,理论上支持N多任务同时执行。

自动化步骤应该有哪些

  1. 需求bug等管理工具,参考工具jira,禅道等
  2. 源码管理工具 gitlab 差不多是行业标准了
  3. 代码质量检测 sonar 很棒的java代码检查工具,可以个性化定制检查项
  4. 编译工具,maven ,gradle(java),npm yarn (node)等等
  5. 单元测试
  6. 制品 (maven,gradle,npm,yarn,docker,tar,zip等)
  7. 仓库 (jar包仓库,镜像仓库,helm应用仓库等)
  8. 部署 (docker,k8s,helm) 目前helm使用的趋势在逐渐上升。
  9. 自动化测试,jmeter等

参考资料链接

  1. k8s中文社区: https://www.kubernetes.org.cn/
  2. jenkins官网: https://jenkins.io/zh/
  3. jenkinsX 官网: https://jenkins.io/zh/projects/jenkins-x/
  4. jenkinsX 平台: https://github.com/jenkins-x/jenkins-x-platform
  5. docker官网: https://www.docker.com/
  6. dockerhub站点: https://hub.docker.com/
  7. gitlabCI说明: https://docs.gitlab.com/ee/ci/
  8. 搭建gitlabCI: https://about.gitlab.com/product/continuous-integration/
  9. sonar质量检查: https://www.sonarqube.org/
  10. helm说明: https://helm.sh/
  11. 前端构建神器 : https://yarn.bootcss.com/
  12. 开源对象存储: https://docs.min.io/cn/
  13. 接口自动化测试 jmeter : https://jmeter.apache.org/
  14. git教程: https://www.liaoxuefeng.com/wiki/896043488029600

Search

    欢迎添加我的个人微信号

    个人微信哦

    Table of Contents