git 和 docker 黄金搭档

jopen 9年前

原文  http://dockone.io/article/916


首先介绍我们公司和团队的情况,kingdee 云之家,主要是做企业社交,其中包括 im,微博等,我们的服务主要包括免费的公有云服务,和各个企业的私有云部署,其中万科,海尔都是我们的客户。

再看看我们现在的系统和技术栈的情况:

  1. 现在的系统中存在 449 项目
  2. 开发使用的技术栈有 java(标准容器项目使用 jetty,play 项目),nodejs,php,百花齐放。
  3. 两条产品线,将近 100 来号开发人员
  4. 我们还有很多企业的私有云部署需求

在如此多项目和人员情况下,产品迭代又非常快,这就要求我们能够支持开发部门。下面我们说说在如此情况下我们遇到的一些实际问题:

开发工程师说:

  • 谁又收走了我 MQ 中的数据
  • 谁改动了 API 的代码,导致我的程序代码报错
  • 本地程序修改部署,其中出现个以上问题,一上午就过去了
  • 。。。

测试工程师说:

  • dev 环境老是在部署,导致没有办法测试
  • 测试一个 bug 时,别人提交了代码,导致另外的 bug

产品经理说:

  • realease 分支的代码合并导致了将其他没有完成的功能发版正式环境
  • 由于相互依赖导致自己开发好的功能必须等其他人
  • 以上问题导致功能进度不能如期

上面的各个角色都有自己的痛点,我们来分析下上面的情况造成的原因,其实大部分的情况是由于各个环境的隔离不够造成的,知道原因后我们来看看我们的应对策略:

  • 划分好各个角色的边界
  • 采用 Pull-Request 的做法

那我们先来看看我们的基础设施和角色:

git 和 docker 黄金搭档

  1. 开发工程师
  2. 测试工程师
  3. 产品
  4. 其他

然后我们再来划分下各个角色的边界:

git 和 docker 黄金搭档

  1. 开发工程师应该只用关注 git 上的代码和 jira 上的 bug 和 newfeature
  2. 测试工程师只关注 jira 的 bug 和 newfeature 的测试
  3. 产品和其他人只关注 jira 提交的 bug 和 nrefeature 的解决

角色的划分,和我们的基础设施看完了,来看看现在 git 上的分支视图,假设我们现在有两个主分支

git 和 docker 黄金搭档

  1. master: 代表的开发部分稳定分支
  2. release: 代表线上稳定分支

我们的角色边界和基本涉及到的设施够看完了,现在看看开发工程师如何工作的:

git 和 docker 黄金搭档

  • 第一步:根据 jira 上 bug 或者 new feature 从 master 上 fork 一个对应的分支 iss001
  • 第二步:开发工程师,在 fork 的分支上提交代码,git hook 会通知 jenkins build 相应的 image
  • 第三步:jenkins 会把相应的 image 部署到服务器集群中,开发者就可以通过
    iss001.kingdee这个域名访问刚刚对应分支的服务了,iss001 对应的 fork 分支的名称,我们要求唯一

我们来看看测试工程师是如何工作的:

git 和 docker 黄金搭档

  • 第一步:测试工程师经过验证后,这个 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 这样的二级调度就可以平衡资源,节约成本,我们暂时没有这样的需求。至于文档方面我也没有深入研究,建议看官方文档。
</div>