Silence & Solitude makes...

Pu's mind space

开发环境的虚拟化

随着Docker越来越火,产品的持续集成,测试,甚至交付(部署)都越来越倾向于使用容器来进行’标准化’.痛苦往往发生在不明白为什么要这么做就被迫跟着走.
但是用着用着确实能感觉到一些方便的地方.我想作为产品开发者,应该是这个Docker化的方案里受益最少的了吧.

最近在关于开发环境如何和Docker集成颇感头疼.最好的结果是开发者能在开发机器上直接使用于测试团队一致的环境进行初步测试/单元测试.对于脚本语言还好–因为开发者需要的其实仅仅是一个文本编辑器而已.但编译语言就不同了,需要编译.如果需要把测试人员的那一套弄到开发者本地,编译这一步到底应该在Docker里面做还是在Docker外面做?拿java来说,IDE一般都支持热部署,其效果就是修改某个java文件后不需要整个替换war包,IDE应该是增量替换了explored的artifact里面的部分class,重新build是很稀少的情况,因此代码-ide-测试是联系在一起的.而如果要测试基于Docker的产品,那么必然需要对每一个改动进行build,对于大的项目,这显然是个灾难.

2017-08-20 更新

去年这个时候的理解还是比较肤浅的,更新一下:

首先澄清初始问题,依据12-factors的要求:Make the tools gap small: keep development and production as similar as possible.
现在看来这里要求的开发和生产环境的一致性其实是在要求CI/CD环境的一致性,或者具体点,是Jenkins Build Node和Production Node的一致性。由于容器技术的引入,其实小环境一致性的要求是自然满足的,而Node系统以及Docker-Engine本身(版本的)一致性,可以很容易地通过复用诸如Chef recipes或者Openstack Heat Template来达到,至于容器编排器的不一致性 – 譬如在Jenkins Slave上用的是docker-compose而在生产环境中使用Kubernetes – 可能造成的问题,我想是Operation需要解决的,毕竟DevOps的存在只是为了让Ops日子好过点,而不是让Ops失去存在的必要。

然后回到开发者视角,具体的问题是:开发者本机上跑的那个开发中的应用/服务应该以容器的形式调试吗?
这是本文最初关注的问题,因为我当时把开发环境理解成了开发者环境,现在看来这个问题已经没有多少意义了,答案是随便。如果是java开发的话,可能你本机的jdk版本跟容器里的jre版本一致比较好,但是其实也无所谓,如果有一些这种环境差异带来的问题,也会以CI的单元测试失败的形式暴露出来。甚至你的开发机器也可以不需要装Docker,因为有Contract Test的保证,你的应用/服务与其他组件集成时可能出现的问题也会在CI过程中以inter-service测试失败的形式暴露出来。当然如果你希望少一点这种类型的返工,还是需要尽量保持开发机器中的单元测试和CI环境下的环境经可能一致 – 在CI里尽可能调用Gradle Task可以很好地帮助我们实现这一点 – 但是这不是必要的,我想说的是12条军规中的关于开发和生产的环境一致性要求是在要求CI和CD的一致性,而非开发者环境和CI环境的一致性,所以作为开发者来说,这个问题可以忽略。