git 和 docker 黄金搭档
jopen 9年前
原文 http://dockone.io/article/916
首先介绍我们公司和团队的情况,kingdee 云之家,主要是做企业社交,其中包括 im,微博等,我们的服务主要包括免费的公有云服务,和各个企业的私有云部署,其中万科,海尔都是我们的客户。
再看看我们现在的系统和技术栈的情况:
- 现在的系统中存在 449 项目
- 开发使用的技术栈有 java(标准容器项目使用 jetty,play 项目),nodejs,php,百花齐放。
- 两条产品线,将近 100 来号开发人员
- 我们还有很多企业的私有云部署需求
在如此多项目和人员情况下,产品迭代又非常快,这就要求我们能够支持开发部门。下面我们说说在如此情况下我们遇到的一些实际问题:
开发工程师说:
- 谁又收走了我 MQ 中的数据
- 谁改动了 API 的代码,导致我的程序代码报错
- 本地程序修改部署,其中出现个以上问题,一上午就过去了
- 。。。
测试工程师说:
- dev 环境老是在部署,导致没有办法测试
- 测试一个 bug 时,别人提交了代码,导致另外的 bug
产品经理说:
- realease 分支的代码合并导致了将其他没有完成的功能发版正式环境
- 由于相互依赖导致自己开发好的功能必须等其他人
- 以上问题导致功能进度不能如期
上面的各个角色都有自己的痛点,我们来分析下上面的情况造成的原因,其实大部分的情况是由于各个环境的隔离不够造成的,知道原因后我们来看看我们的应对策略:
- 划分好各个角色的边界
- 采用 Pull-Request 的做法
那我们先来看看我们的基础设施和角色:
- 开发工程师
- 测试工程师
- 产品
- 其他
然后我们再来划分下各个角色的边界:
- 开发工程师应该只用关注 git 上的代码和 jira 上的 bug 和 newfeature
- 测试工程师只关注 jira 的 bug 和 newfeature 的测试
- 产品和其他人只关注 jira 提交的 bug 和 nrefeature 的解决
角色的划分,和我们的基础设施看完了,来看看现在 git 上的分支视图,假设我们现在有两个主分支
- master: 代表的开发部分稳定分支
- release: 代表线上稳定分支
我们的角色边界和基本涉及到的设施够看完了,现在看看开发工程师如何工作的:
- 第一步:根据 jira 上 bug 或者 new feature 从 master 上 fork 一个对应的分支 iss001
- 第二步:开发工程师,在 fork 的分支上提交代码,git hook 会通知 jenkins build 相应的 image
- 第三步:jenkins 会把相应的 image 部署到服务器集群中,开发者就可以通过
iss001.kingdee这个域名访问刚刚对应分支的服务了,iss001 对应的 fork 分支的名称,我们要求唯一
我们来看看测试工程师是如何工作的:
- 第一步:测试工程师经过验证后,这个 bug 或者 new feature 的功能完成,会把代码 merge 进入
master分支,在这分支上做性能测试和冒烟测试 - 第二步:经过性能测试和冒烟测试后,就可以通过 cherry pick 挑选要发布的功能
- 第三步:经过发版后的,测试工程师关闭 jira,我们通过 web hook 通知后端 k8s 集群删除对应分支分配的资源
这就完成了整个系统的流程,这其中每一个分支都可以分配资源部署环境测试和开发。
- Q1:开发每提交一个bugfix,都会触发jinkens去构建镜像,那么多的开发者,岂不是要构建很多镜像?
- A:没有错,我们是每次都触发构建 image,由于 image
是分层的,底层已经存在的父对象,是不用存储,只存储变化的部分所以再用的磁盘空间很低,在系统开始初,我做过统计, 1000 个 image 也不到 9G,这其中还有很多基础镜像。 - Q2:想问一个集群相关的,像docker部署这部是直接调用docker部署容器,还是通过ansible或其他工具
- A:有了 k8s 管理集群后,发布的工作就比较简单了,用不上 ansible。但是 ansible 还是有它的用处的,比如清理集群中过时的
image,和已经退出的 container等。 - Q3 你好,以前也做过类似的服务“第三步:jenkins 会把相应的 image 部署到服务器集群中,开发者就可以通过 iss001.kingdee这个域名访问刚刚对应分支的服务了”,单独一个分支解决了对应的bug,但实际生产中非常容易修改一个bug引起其他的 bug,你们是怎么去把控整体的稳定性?如何提高这种单个bug分支单个测试环境的意义?
- A: 这个 pull-request 的工作方式是应对功能开发的,如像长期开发某个 new feature,你刚刚说的一个 bug 产生另外一个 bug,我们的做法是有回归测试,我们有一个 smoke 分支,持续不断的对其做功能回归测试,只有通过的才能 cherry pick 到 release 上
- Q4:测试环境依赖的redis/MQ之类的外部服务如何做的隔离?每次测试单独拉起来一套外部依赖的服务吗?
- A:我们通过多个手段来实现
共享数据:master,smoke,release 分支测试都有自己独立的中间件
要是不用访问共享的数据,可以部署如 MQ image
代码层面的,如 MQ key 的名称加上机器的 IP
Q5:有没有用到mesos?是否容易遇到问题?这方面的文档好像并不多
A:mesos 是个二级调度,适用于像存在多套集群的情况,来均衡资源,如:部署了 hadoop 和 storm ,一般会使用 storm 来处理实时的请求,hadoop 做离线工作。晚上和白天就存在一种可能就是 hadoop 闲置,但是 storm 可能很忙,这时 mesos 这样的二级调度就可以平衡资源,节约成本,我们暂时没有这样的需求。至于文档方面我也没有深入研究,建议看官方文档。