个人简介 王振威,Coding 系统架构师,自封一个很二又很认真的程序员,多年系统软件开发经验,擅长 Linux,Golang,Java,Ruby,Docker等技术领域,进两年来一直在Coding从事系统架构和运维工作,领导公司技术团队进行技术革新,并推进Docker在公司内部私有云平台中的实践。
全球架构师峰会(International Architect Summit,下简称ArchSummit)是由InfoQ中文站主办的一次全球性架构师峰会。ArchSummit专门针对架构师人群,讲述与架构和架构师相关的各方面趋势、技术和案例。这也是继QCon之后,InfoQ中文站主办的又一次高端技术盛会。
1. 各位InfoQ的网友大家好,现在我们是在ArchSummit的北京现场,作客我们专访间的是Coding的软件架构师王振威,第一个问题先请您做一下自我介绍,跟介绍一下您在Coding从事的工作。
王振威:大家好,我是来自Coding的王振威,我现在在Coding主要做基础软件架构的改进以及运维方面的工作。我是在Coding创始的时候就加入这个团队,一直做到现在,之前主要做的是代码托管相关的工作,现在主要做运维和架构的改进。
2. 刚才您谈到您是从一开始就加入Coding,能否谈一下您之前的从业经历以及为什么加入Coding呢?
王振威:我之前在开源中国工作过一段时间,后来机缘巧合就加入了Coding。Coding是初创,我有幸作为创始团队成员之一,我们几个创始人做了一些比较基础的研发工作,今年就转职做运维和基础架构改进开发。从去年年底到现在我一直在做我们的运维平台的容器技术,也就是Docker的架构引进,以及做一些开发工具相关的工作。
3. 我看Coding这边,Docker用的比较多,您能谈一下您个人对于Docker技术的理解,以及为什么Coding选择Docker这种方案吗?
王振威:我们之所以选择Docker作为我们下一步的架构的计划,主要是因为我们之前遇到了一些问题,我们系统比较复杂,牵扯到各种各样的编程语言和框架,这些框架和编程语言做出来的软件、服务程序,交给运维去处理的时候非常痛苦,因为运维不清楚软件具体需要什么样的环境。有了Docker以后,它把整个软件、环境都打包成一个整体。作为运维来讲,对于任何一个程序我们都认为它是一个基础的容器,我们只需要给它分配相应的资源它就可以运行。首先容器在概念上跟我们遇到的问题是比较吻合的,所以我们选择了这样一个解决方案。Docker也是容器里面目前最成功的,所以我们选择了Docker。Docker本身有一个口号,叫做build,ship and run,我们也是基于这个出发点将我们的架构一步一步演化的。
4. 你对Docker的理解其实还是基于它的Slogan?
王振威:对,我认为docker的核心就是build,ship and run,它的其他高级的功能我们之前也尝试了,最后都放弃了,应用的最终结果就认为,它最核心也最属于中间力量的功能就是这个build,ship and run
5. 您能谈一下现在Coding是如何用Docker技术的?您之前做开发现在做运维,这个过程中肯定踩过好多坑,你挑两个比较典型的给我们解释一下是怎么解决的吧?
王振威:OK,我们现在用Docker是采用了自己写了一套简易的编排软件,比较像Docker官方的compose工具。用的Docker也就是一些比较基础的功能,比如打包,用它的网络也是用host模式,我们没有用它提供的日志功能用的自己文件系统mount进去,也就是说我们并没有使用Docker比较高级的功能,只使用它比较基础、比较可靠的功能作为我们的服务支撑。我们在Coding的架构演化主要遵循的理念就是平滑演进,能从传统架构慢慢变到最终的Docker环境里面。我们用Docker的过程中也会遇到一些问题,两个问题,一个是在Docker的可能是1.9版本以前,具体我不太记得,有这样一个Bug,它的容器的标准输出在输出大量数据的时候,容器会挂掉,甚至Docker daemon会挂掉,内存会出现爆炸式的上涨,直到docker daemon被操作系统oom。我们找到重现方案,并给官方提供了重现方式,他们在1.9.1,也可能这个修复还没有上到最新的release里面,但是这个Bug已经被他们修复了,这是其中一个。另外我们之前有一个应用场景,用户每进来一个请求我们都要启一个新的容器的场景,我们每天都有几十万的请求的量,后台只有三、四台服务器处理这样的请求,最后导致Docker daemon内存会缓慢增长。另外它的文件系统出问题了,container在停掉的时候,会残留很多小文件,最终导致文件系统的inode结点被占满,从而导致Docker daemon无法正常工作。这是另外一个问题,后来我们还是采用了使用单个进程处理的方式解决。Docker可能在某种条件下不适合用每一个请求都起一个container这种完全理想的状态下去处理我们的业务逻辑。
6. Docker跟存储和数据库怎么配合?之前Docker不能做存储,后来它好像又集成一些东西做存储,你们有没有遇到过跟存储相关的问题?
王振威:我们都是直接用文件系统mount到Docker容器里面,包括数据库也是这么干的,近期,我们上个月才完成了一次把我们主站的数据库迁移进Docker的工作,也是使用文件系统直接把数据库的文件目录mount进容器里面启动。
7. 挂载完之后如果要做数据迁移呢?你们可以直接做吗?
王振威:如果是做热迁移,我们就使用数据库的镜像机制,直接把数据同步到另外一个slave机,再通过业务层面迁过去。如果是冷迁移也好办,就是把容器停掉,把目录通过工具再传输到另外一个服务器上去。大致就是这样。
8. 最近我们看到Coding正在全面推进各个应用组件在Docker中构建项目,并且在Docker中运行,现在进行到什么程度?
王振威:我们现在的组件已经进行到大概90%都是在的Docker中运行。在Docker中构建分为两部分,一个是生产环境,一个是开发环境的构建。现在开发环境正在推进一种叫Coding local的机制,就是开发环境所有的测试、调试组件都运行在Docker里面,而且编译在Docker里面。为什么编译在Docker里面?存在一个问题,我们的生产部署环境都是 Linux,但是本地的开发环境可能有Windows、mac,我们担心因为编译工具链包括编译环境不同会导致一些问题,所以强制要求开发者都把程序原码放在Docker容器中构建。很简单,把Docker原码目录mount进Docker容器。比如说golang,你把golang的原码mount进去,然后使用golang1.5 Docker基础镜像,里面已经装好了Docker相关的工具链,编译好以后把二进制文件拷贝出来,这个二进制文件就是一个在Linux上ready to run的包,再把这个包打包进Docker image,我们的构建工作就完成了。生产环境和开发环境我们的目标期待是一样的,但是现在还存在一些便利性的问题,生产环境可能不需要考虑便利性,只是要最终的安全、稳定,但是本地很多时候要考虑一些便利性的问题,所以目前两者还没有完全融合到一起,但这是我们的一个目标。
9. 刚才您说开发环境,我又想到一个问题,如果编译器的版本有一些update,这时候容器需要再重新生成吗?
王振威:我们之前也遇到过关于编译器的版本,比如说Java JDK7和JDK8,它们编出来的class文件是不兼容的,我们系统中也有不同的应用会用到JDK7和JDK8,我们自己会维护一个基于官方的JDK7和jdk8衍生的基础镜像,在这个基础镜像里面我们会做其他的定制,比如说时区、local的设定,让它更适合于我们的条件,开发者把程序交付给运维的时候,必须告知我们这个程序要在什么环境下编译是用maven或者gradle。我们会选择合适的image把原码打包进去进行构建。要求的是生产环境和开发环境都是一致的。
10. Coding如何将原来本地运行的程序的构建过程转移到Docker当中去?
王振威:刚才我也大致提到这一点,问题在于很多时候我们本地的电脑上可能只允许你安装一套JDK,或者你也可以装多套开发环境,比如说ruby很多版本你可以装rvm解决,JDK很多版本可以通过其他方式解决,但是如果有了Docker这些问题就天然解决了。
11. 比如说环境变量?
王振威:这跟环境变量没有什么关系,比如说我们需要JDK7编译时候,就把Docker file中的JDK1.8改成1.7就可以了,需要1.8的时候,就把1.7改成1.8。编译出来的文件是相应环境下的二进制文件。
12. 这个Docker image是同一个吗?
王振威:不是同一个,不同的环境肯定要打包不同的。
13. 据我们了解Coding现在并没有使用现成的容器编排系统,是自己写了一套,为什么这么做?
王振威:我们做过一些考量,比如K8S我们有在内部尝试用它,但是发现它非常不接地气,具体来讲,第一它有很多高级复杂的功能我们目前是用不到的。第二我们需要的一些功能它是没有的。另外一个问题如果我们整站或者说整体一套系统迁移到K8S我们的成本跨度非常大,这是最重要的原因。我们没有办法一步一步把我们环境演进成K8S。所以我们做的是基于现有的架构慢慢把我们现有的进程、服务搬到Docker。现在主要做的这样一个工作。
14. 好像国内基本上用K8S的不是很多,那些大的电商都是自己写的一套系统,不大用K8S,就是因为它不接地气,是因为我们国内外开发的东西不一样还是因为业务上的不一样?
王振威:我觉得真正深入的去使用Docker这种团队,最终不一定会选K8S的原因在于我们都是基于现有的架构去演化,并不是全新的从零开始的一套东西,如果从零开始的话,整个程序最开始设计就可能会考虑使用K8S,或者应用设计会更倾向于向它靠拢,这样的话用起来就会非常方便,它也会成倍提升开发和运维的效率。但是如果是一个既有的系统一下子跨度到K8S,迁移成本太高,而且风险太大,一般公司无法承担。
15. 大家对K8S的稳定性和与自己系统的适配是有疑虑的。
王振威:对。
16. 您认为目前Docker还存在什么问题吗?比如网络安全问题,还有没有其他问题?
王振威:Docker的问题在于现在扩的面有点太宽了,需要更注重作为容器的基础功能的研发。比如说它现在一些比较杂乱的没有什么意义的功能,不过也可能我是从使用者角度考虑,他们从Docker公司领导者的角度考虑,可能会有不同的意见。我认为他们做的一些,比如像Docker machine、swarm,包括Docker的多种网络模式,这些跟容器本身没有太大的关系,Docker本身需要更专注于搞容器技术,他的口号喊的比较好,快速交付。另外一个容器本身就是为了解决隔离性和安全性的问题,我觉得他们需要更多的着重这方面。
17. 刚才你说到安全性,因为Docker官方宣布他们有两个安全方面的强化措施,其中一个是用物理的Key对容器进行签名,你觉得这会不会在一定程度上改善容器的安全性?或者说这个东西,我还要整一个硬件过来,在国内这个是不是好推?
王振威:关于安全性问题,尤其对容器或者对镜像签名的工具我认为是有必要的,尤其在公有云上,比如我们下载一个软件,Docker image编译到最后它也是一个程序包,就是一个程序,这个程序不管传到哪,可能在某个过程中就被人篡改了,会出现一些问题,所以签名也是必要的,但是签名有没有必要用硬件确实是另外一个程度的考量,比如我们可以用PGP之类工具来做这个工作,因为它毕竟是一个文件,跟其他的文件没有什么区别。另外一个在私有云里面,可能需要更关注的是关于网络,包括资源的隔离性这方面的一些考量。
18. 安全方面还做了另外一个工作,就是对容器进行安全扫描,比如说突然爆发了某一个漏洞,我们随便举个例子,假如用的是Java的某一个环境,但是java现在出现了一个反序列化的突发漏洞,他会对这个漏洞扫描然后官方及时打补丁,这个措施会不会更好?你们是不是会做这方面的工作?
王振威:这个做得还是很好的,我们不管是用容器、操作系统还是各种的生产环境,毕竟最终Java的程序是要靠Java运行时驱动的,如果Java的运行时有BUG,不管什么样的环境都需要及时解决这个问题,所以我觉得Docker在这方面还是做得很好的。
19. 最后一个问题,你觉得未来容器技术的发展方向是什么?基于这个发展方向,Coding会怎么做?
王振威:现在容器也有好几家在做,包括一些业界的巨头,他们共同成立了一个组织叫open container,这可能是容器未来的发展方向,Docker也会渐渐向open container接口靠拢,以后容器可能就不再是Docker一家独大,像一些企业,比如说vmware、GOOGLE,他们内部的容器如果能接入open container的接口,那我们的选择就会更多。
20. 你是说大家都是一家?
王振威:大家都遵循这种公开的接口,我们不会受一家所累,因为大家的接口都统一的,比如虚拟机你用AWS的虚拟主机,某一天想迁移到ucloud或者阿里云,在底层来讲他们虚拟机的镜像都是可以共享的,所以是有这种迁移能力的,因为他们遵循了同样的接口。
InfoQ:好,谢谢你接受我们今天的采访!