初创公司应该如何做好持续集成和部署?

作者介绍

裴双才,Geekwolf,现MAKA运维负责人,博客: http://www.simlinux.com。《FastDFS分布式存储实战》作者,《Ansible中文手册》译者。RHCA/RHCVA,混迹各种开源社区,专注高效运维、DevOps、性能优化、Docker、MySQL等方向,热衷技术分享,欢迎一起讨论技术,互相学习,共同进步。

前言

持续集成和部署是每一个互联网开发团队都必须要面对的问题,特别是在初创公司,由于业务和技术团队快速增长,技术积累较弱,所以一个高效的,可持续的运维规范尤为重要。

最近一段时间,一直在梳理项目开发流程以及自动化测试和部署规范,作为一个总结和大家分享,希望有所帮助。

高效可持续的运维环境需要合理的规范作为支撑:

  • 应用管理规范
  • 权限管理规范
  • 配置变更规范
  • 发布策略规范
  • 日志运维规范

持续集成部署实战(该内容将在后续文章中进行讨论,本次不展开)

一、应用管理规范

1. 应用版本化

可以使用SVN、Git对代码进行版本控制。

建议使用Git(如:GitLab),并使用Git Group命名规范:大原则为根据产品域名区分,或者根据前后端业务模块进行分组(小写字母命名,横杠[-]作为连接字符)。

举例:

MAKA官网 http://www.maka.im 对应的Git仓库Group为official,按照功能模块分组,商城前端对应的Git仓库Group为store。

项目名命名规范:

  •     全部用小写字母
  •     横杠[-]作为连接字符
  •     命名规则:[产品名称]-[项目类型]-[自定义名称]

举例:

official-store-customer。

实践建议:在创建项目仓库时就要权衡前后端或者大的功能模块的拆分,保持低耦合度。

2.合理的分支策略

常用的Git工作流总结如下:

第一种:集中式工作流,很多公司使用SVN,对Git的使用并不熟悉。如果迁移至Git之后,可以考虑集中式工作流进行开发,即代码库只有 master 一个分支,所有开发者只有本地 master 和远端 master 分支。这种方式使用简单,但无法充分发挥 git 的优势。

第二种:功能分支工作流, 与上一种不同的地方在于,除了 master 分支以外还有功能分支。日常开发在功能分支,提测集成时提交Merge Requests(在Bitbucket中是Pull Request)。

开发者可以在这个时候进行讨论、审核代码,同意后可以合并至 master 分支,未同意则可以让开发者修改后重新提交或者选择关闭该MR。

举例: third-party-login-feature

三种:Gitflow工作流,两个主干分支 master(正式发布分支)和 develop(功能集成分支)。

开发者应基于 develop 分支创建 feature 功能分支,用于开发,开发完成后提交merge requests请求合并进 develop 分支。

此时若到了发布窗口,基于此时的 develop 分支创建发布分支 release 用于测试 → 预发布 → 发布,以避免影响 develop 分支的正常集成、合并功能分支;release 分支不再有新的功能合并进来,一旦创建只用于 bug 修复并将修复 cherry-pick 到develop分支;发布完成后,release 分支合并进 master 并分配版本号、打tag,用于存放发布历史。

Gitflow工作流方式适用于大型项目

第四种:Forking工作流,开发者 fork 官方的 repo 到自己的账号空间,对于官方分支只有只读权限,开发者通过pull request 提交给官方审核是否合并进代码库;开发者通过同步上游官方的 repo 来使用其他人的代码,分支策略可参考上述三种工作流,适合开源项目。

针对创业公司参与同一个项目的开发者并不多,过于复杂的分支策略并不能带来便利,可以参考 leancloud 的分支模式,根据团队的使用情况进行调整。

介绍下我们当前使用的分支策略:

  • master:主干分支,用作日常开发的基线;
  • userA:开发者A日常开发所在分支;
  • release-201603091106: master分支集成测试完成后,构建到预发布环境时自动创建 release-201603091106 用于发布。
  • hotfix-201603091106: 基于当前发布之后的 release-201603091106 分支用于修复bug,通过提交merge requests 方式合并进 release-201603091106,并将修复 cherry-pick 到master分支。

日常开发在 userA 分支操作,然后提交merge requests 请求合并至 master 分支,本地通过 git fetch origin master,然后在 userA 分支 git rebase origin/master 将 master 最新 commit 合并到本地 userA 分支从而形成闭环开发。

3.关于代码审核

三剑客 GitLab + Jenkins + Gerrit。

Gerrit作为创业公司代码审核工具略显复杂,不足够敏捷,建议使用GitLab的 Merge Requests 或者 Github 和 Bitbucket 中的 Pull Requests 作为代码审核和讨论的工具。

也可以选择 Facebook 的 Phabricator (可同时作为代码托管和评审,非常敏捷,由于 Phabricator 提供的工具集在 Windows 下使用起来不太友好,后来没有选用,后期会分享 Phabricator 的使用思路和工作流)

4.目录结构

规范的目录结构不仅有利于开发者理解代码结构,更有利于代码的快速部署,以PHP为例,目录结构建议将代码配置文件(如:数据库,Redis,OSS Key,语言开关,日志级别开关等)、日志文件,其他文件缓存等独立于代码库之外存放。

前端项目 src 为源码目录,dist为前端经过压缩合并等最终生成的代码目录(发布时可忽略src)。

每个项目详细写 README.md 文件,详细说明,各个环境对应的访问路径、目录说明、构建压缩方式,Nginx配置等,代码仓库中包含额外的 test 目录存放测试用例(本着谁开发谁写测试用例的原则)。

二、权限管理规范

权限有两类:一个是系统权限(包括服务器登陆,数据库/Redis等),另外一个是服务运行时的权限。

1. 系统权限

统一入口,受限访问IP,禁止空密码弱口令,生产环境服务器需要先拨入vpn之后通过跳板机才能连接成功(当然我们使用的是开源当中最好的跳板机Jumpserver),任何人的操作都需要审计;

生产数据库及Redis禁止了外网访问,分别使用phpMyAdmin和RedisLive统一访问入口,增加了多主机访问及屏蔽了危险操作如DDL 数据的导入导出等。也需要先拨入vpn才能访问。

开发测试环境权限控制相对宽松,DEV Leader 和 QA Leader同时具有开发和测试环境的服务器及数据库权限,便于测试和Debug;

生产环境为了便于开发调试生产代码,且不影响线上,增加了 Staging 节点,未在线,但环境代码及后端均和生产一致;

2. 针对服务权限层面

以 Web 服务为例,Nginx 和 php-fpm 运行用户和用户组为:www-data;代码目录用户为www。

这样代码目录默认情况下web服务只读,避免出现文件和目录777权限的情况;

日志和缓存目录用户设置www-data,但要禁止访问php等动态文件。

禁止危险函数phpinfo exec eval system 等,具体可参考

http://www.sinacloud.com/doc/sae/php/runtime.html

禁止跨目录访问open_basedir,开启前后的性能对比请参考:

http://www.simlinux.com/archives/1531.html

三、配置变更规范

1.系统部署

传统IDC机房可以通过定制镜像或者使用 Cobbler 定制安装,运行的服务也可以定制在镜像中,但建议安装系统时注册puppet/salt agent,再自动化部署相关服务。

公有云中可以在服务器上部署相应环境后创建系统快照,制作系统镜像,弹性扩容时可选择该镜像自动化安装。

2.日常变更

日常变更包括服务配置的变更和代码配置的变更,这些操作我们是通过 Ansible,相比 puppet/salt 的好处就是简单方便不用装agent,后面会详细介绍如何基于Ansible做发布回滚。变更的内容使用git进行版本控制。

四、发布策略规范

1. 发布时间

注意:以上请根据自己业务做相应调整,避免在业务高峰期发布(除应急bug外)。

我们业务高峰期基本在18:00-23:30,低峰期基本在01:00-06:00。这也是微信分享阅读的高峰和低峰时段。

无论应急Bug还是日常迭代都必须由QA测试通过和产品经理审核通过后才能上线。

血的教训:曾经出现过开发为了修复线上很急的bug,开发修复后自主上线导致生产出现更严重的问题。

2. 发布工具的选择

无论是自主开发发布系统,亦或是使用开源的系统都要本着解决问题的原则,否则只能是重复造轮子,然并卵呀!

开源的持续集成和发布里面个人觉得比较好的如:Jenkins,Walle,Spinnaker,go,Gitlab-ci,Bamboo(收费)等,其他参考。

https://github.com/geekwolf/sa-scripts/blob/master/devops.md

下面介绍我们基于GitLab + Jenkins + Ansible(Flamingo自动化代码发布工具)实现的自动化代码部署平台,流程如下:

Flamingo:(“火烈鸟”,https://github.com/geekwolf/flamingo)是基于Ansible的自动化代码发布工具,目的是实现统一的代码发布方式,思路基于Capistrano,并对Ansisrano进行了改造可以通过传入语言环境,主机组(应用组/灰度机组等),项目代码库,分支名称,项目名称等参数来进行自动化打包发布,也可以将Flamingo工具二次打包使用。

Flamingo本着回滚即发布的原则,以简化发布流程,回滚时传入要回滚的分支即可,其他参数可参看defaults/main.yml进行了解;(注:依赖Git/rsync/ansible)

例子:


  1. ansible-playbook deploy.yml 
  2.  
  3. --extra-vars='flamingo_git_repo=git@github.com:geekwolf/flamingo.git flamingo_product_name=flamingo' 

执行后生成的目录结构如下图(目录定义请参考defaults/main.yml):

五、日志运维规范

毫无疑问,规范的日志对于运维和开发排查问题有非常大的帮助,例如PHP项目日志格式可以规范为时间,日志级别,日志内容(比如对于连接多个DB时出现连接不上或超时应该把实例地址一同写入日志),可以参考psr-3的标准:

http://www.php-config.org/psr/psr-3

通过ELK将业务日志,PHP自身错误日志/慢日志,Nginx慢日志等进行搜集统计并结合Zabbix实现报警,便于及早发现问题。

六、持续集成部署实战

后续篇章会分享针对PHP/JAVA/前端以及Android/ios持续集成和部署实战,敬请关注。

总结

以上只是粗略对持续集成和部署过程中遇到的问题进行了总结,并不完美,但对于初创公司应该有些帮助,欢迎一起学习讨论!

作者:裴双才

来源:51CTO

时间: 2024-10-30 08:29:11

初创公司应该如何做好持续集成和部署?的相关文章

持续集成及部署利器:Go

Go是一款先进的持续集成和发布管理系统,由ThoughtWorks开发.(不要和Google的编程语言Go混淆了!)其前身为CruiseControl,是ThoughtWorks在做咨询和交付交付项目时自己开发的一款开源的持续集成工具.后来随着持续集成及持续部署的火热,ThoughtWorks专门成立了一个项目组,基于Cruise开发除了Go这款工具.ThoughtWorks开源持续交付工具Go,Go的官方网站是http://www.go.cd/,其文档是http://www.thoughtwo

linux下持续集成自动部署脚本,自动从jekins拉取war包并重新部署 (我去,一个大坑,if中的变量要双引号引起来,不然始终是true)

[root@localhost tomcat-gl-8082]# cat deploy.sh  rm -rf webapps/gl/* rm -rf gl.war wget -qc "http://192.168.0.102:9000/jenkins/job/gl/ws/gl.war" echo "正在解压" unzip gl.war -d webapps/gl >/dev/null 2>&1 cp -r /configbak/gl/* weba

谈谈持续集成,持续交付,持续部署之间的区别

经常会听到持续集成,持续交付,持续部署,三者究竟是什么,有何联系和区别呢? 假如把开发工作流程分为以下几个阶段: 编码 -> 构建 -> 集成 -> 测试 -> 交付 -> 部署 正如你在上图中看到,「持续集成(Continuous Integration)」.「持续交付(Continuous Delivery)」和「持续部署(Continuous Deployment)」有着不同的软件自动化交付周期. 持续集成 持续集成是指软件个人研发的部分向软件整体部分交付,频繁进行集成

微服务的持续集成,四步“构建”一个代码世界

本文讲的是微服务的持续集成,四步"构建"一个代码世界,大师Martin Fowler对持续集成是这样定义的:持续集成是一种软件开发实践,即团队开发成员经常集成他们的工作,通常每个成员每天至少集成一次,也就意味着每天可能会发生多次集成.每次集成都通过自动化的构建(包括编译,发布,自动化测试)来验证,从而尽快地发现集成错误. 今天我们就来聊一聊微服务的持续集成. 目录 一.持续集成之构建 二.持续集成之部署 三.持续集成之测试 四.持续集成之发布 五.总结 一.持续集成之构建 当微服务产生

通过Docker容器运行持续集成/持续部署

本文讲的是通过Docker容器运行持续集成/持续部署,[编者的话] 对于Docker主流的应用场景:持续集成和持续部署(CI/CD)大家也许并不陌生.这篇文章从独特的视角阐述了如何利用各种云平台构建属于自己的CI/CD容器,笔者还自己扩展了Gitlab CI引擎,对CI感兴趣的同学对这个文章应该很感兴趣. 我曾经使用Docker了一段时间,在过去的一年里伴随着众多的Docker容器涌入,帮助用户们更容易的部署Docker容器到生产环境中.一些工具是第三方公司提供,当然也包括Docker公司自己的

什么是持续集成?持续交付?持续部署?

作者: 阮一峰 互联网软件的开发和发布,已经形成了一套标准流程,最重要的组成部分就是持续集成(Continuous integration,简称CI). 本文简要介绍持续集成的概念和做法. 一.概念 持续集成指的是,频繁地(一天多次)将代码集成到主干. 它的好处主要有两个. (1)快速发现错误.每完成一点更新,就集成到主干,可以快速发现错误,定位错误也比较容易. (2)防止分支大幅偏离主干.如果不是经常集成,主干又在不断更新,会导致以后集成的难度变大,甚至难以集成. 持续集成的目的,就是让产品可

《移动App测试的22条军规》——第23章,第22节实现微信App的持续集成和持续部署

23.22 实现微信App的持续集成和持续部署由于我们并没有微信App的代码,所以我们不能部署微信App的持续集成环境,但是我们可以部分实现微信App的持续部署. 为了实现Android版本微信App生成安装文件并部署到设备上的过程,我们可以首先把微信App的安装文件复制到电脑上的Dropxbox文件夹下(如图23.64所示). 通过以微信App的测试为例,我们实际演练了如何使用移动App测试的22军规来指导测试.虽然笔者演示的内容相对基础,但是相信大家在了解到如何使用这22条军规之后,可以结合

基于Docker容器的,Jenkins、GitLab构建持续集成CI

** 开发者将代码提交(push)到GitLab后,GitLab通过Hook通知jenkins,jenkins自动从GitLab中获取项目最新的源码进行集成和发布. 基于Docker,创建一个私有GitLab的容器,创建一个jenkins的容器** 1. 构建私有的GitLab容器 https://about.gitlab.com/installation/#centos-7,直接安装gitlab,不借助docker 通过docker-compose的方式安装gitlab,docker-comp

如何破局CI工具拉锯战:探寻中小企业的持续集成之路

摘要:随着持续集成技术的不断成熟,各种持续集成相关的开源和商用软件层出不穷,但是对于中小型企业的技术团队而言,往往在进行持续集成实践时会陷入工具之间的拉锯战.那么,对于中小团队而言,如何才能实现高效敏捷的持续集成方案?2017苏州云栖大会云效专场上,南京路特CTO.阿里云MVP戚俊结合实践经验为大家分享了中小团队持续集成之路. 以下内容根据演讲视频以及PPT整理而成. 虽然持续集成的概念已经火了很长时间了,但是因为各个企业的规模以及业务类型都不同,所以在持续集成中遇到的问题也各不相同.本次将结合