作者介绍
周晖,pivotal大中国区云计算首席架构师,有丰富的paas云实际建设经验,负责过国内某知名银行已经生产上线一年的paas云的架构设计和部分功能的实现,参与过某超算paas、某超市电商paas、某电力paas等项目的建设。
上文说到caas生态圈的公司如何应对docker用捆绑方式从容器入侵caas领域,caas厂商通过容器抽象、标准化容器运行时runc以及容器功能外化插件来重新定义容器。下面我们继续来看caas厂商的具体方案。
一、caas业界通过分解重组docker技术来替代docker的方案
1、k8s通过cri-o取代docker容器管理引擎架构
和cloud foundry的架构模式类似,k8s也发展了cri-o来取代docker,架构图如下:

cri-o是google的kelsey和docker cto所罗门论战之后的结果,论战之后,google就提出一个设想,要让k8s调度的容器去docker化,虽然他们一开始说的是要分支出一个docker的分支来做容器,但是后来考虑到这样做属于刺刀见红,杀伤力太大,所以在2016年6月先弄了一个ocid(oci守护进程),就是runc的守护进程,和docker daemon有异曲同工之妙,该项目的维护人员此地无银三百两的说“这不是docker的分支”。
由于ocid过于和docker daemon类似,随后google又把这个项目重新命名为—cri-o(container runtime interface,容器运行时接口,o表示oci,也就是runc的运行时接口),这也反映了google的心态,一方面通过cri对容器进行抽象,什么容器我都支持,另外加一个o,我重点支持oci的runc,显得不是那么白刀子进红刀子出,大家表面上还是和平共处,而且显得立意更高,通过容器抽象层进一步标准化容器,runc只是标准化容器运行时,cri把对容器的调用管理等也标准化,潜台词是docker daemon是非标准的、独家的。
同时,google也在向mesos推销其cri-o,希望mesos也采用其cri-o的架构。
cri-o对容器运行时提供基本管理功能,同时google的k8s提供镜像管理功能(container/images),完全可以取代docker的镜像仓库。k8s一方面支持容器插件技术,另一方面自己也制定实现一些容器插件,最典型的就是容器网络插件,自己定义并实现了cnm的容器网络插件。
因为k8s之前一直支持docker,为了保持一定的兼容性,k8s继续支持docker容器,但是不再支持docker超出标准容器之外的特定功能,也就是把docker的定位和runc等同化,docker做的再多功能也不用。
2、mesos通过unifiedcontainer取代docker容器管理引擎
和k8s类似,mesos也不再只支持docker容器,而且对容器进行了抽象,项目名字直接就叫”unified containerizer”—统一容器。目前还是支持 docker 和 mesos containerizer 两种容器机制,未来就统一到”unified containerizer”。架构图如下:
unified containerizer也支持插件架构,但是和docker的插件不是完全一样,设计的插件类型更丰富,包括三大类:
第一类是进程管理,支持容器之前的进程,这也是mesos一贯的调度管理策略
第二类是隔离器: 在容器生命周期的各个阶段提供扩展接口,保护了docker的几类插件,如网络、磁盘、文件系统、卷插件。
第三类是容器镜像管理,除了容器镜像,还将支持虚机镜像等。
mesos的统一容器基本就包含了dockerdaemon、docker仓库等功能。
当然,由于之前一直支持docker容器,目前阶段mesos还继续支持docker,但是也有自己的mesos containerizer容器机制。
3、cloud foundry通过garden取代docker容器管理引擎
从runc逐步成熟,cloud foundry的容器引擎garden就采用了runc作为容器运行时,如下图:
garden取代dockerdaemon(docker daemon有内有docker server,docker server内有docker引擎),直接调用runc来生成容器运行环境,同时cfgarden也支持容器插件,容器插件是独立进程,在网络插件方面优先支持k8s的cmn插件标准。cf diego有自己的镜像仓库管理,也可以从docker仓库中获取docker镜像部署。
不得不对garden的设计多说几句,garden包括之前的warden,从一开始的设计就是容器抽象,使得可以支持不同的容器运行时,而且garden做了三层抽象,所以garden从一开始就支持.net应用,不是通过windows 2016的容器机制来实现,而是在.net运行时模拟了一个容器的实现,所以garden支持windows的几乎所有版本的.net应用。
k8s cri-o和mesos的unifiedcontainerizer都借鉴了garden的容器抽象设计思路,所以garden也是第一个支持runc的caas/paas。
从这个架构可以看出,cloud foundry的garden基于runc和容器插件,就替代了docker的容器功能,共同的是runc和容器插件,而garden取代docker daemon的容器管理功能。
当然,garden也支持直接部署docker镜像。
二、容器生态的演进
1、各方以runc为核心重新构建容器生态圈,docker容器被弱化
在对开源docker分支进行了反复斟酌、放风声、试探和讨论之后,各方觉得杀伤力太大的方案。而重新回到了折中方案,以runc为核心重新构建生态圈,并且通过插件来弱化容器在caas生态圈的重要性。
我们来看看生态圈的演进示意:
如上图,标识了容器生态圈或是caas的演进变化。
最早只有docker和garden两大主流容器,mesos和google都专注于caas,容器就全部采用docker,cloudfoundry由于在docker之前就推出了warden(后升级到garden)容器,cf采用自己的容器打造了paas平台,形成了一个和谐的生态。
在docker捞过界了,并且确实有些不符合企业生产系统的因素,包括后向兼容性、商标问题、稳定性问题,于是各caas/paas生态厂商组建oci联盟,打造runc容器引擎,只需要一个简单的容器起停、管理等引擎,把docker的容器功能一分为二,runc作为一个简单明了的运行环境,降低复杂度,提升稳定性,适合生产系统。而对于docker容器的其他功能,则在各自的容器抽象层,依据需要去实现,而且因为docker本身集成了太多功能,不利于生产环境稳定性要求,各个容器抽象层都采用插件模式,维持容器的简洁性,需要什么功能再插入容器,比如需要网络就可以插入网络插件,需要存储和卷访问,就插入存储和卷的插件。
目前的形势,就形成了docker和各个caas/paas厂商在同一层面竞争,在caas/paas平台,docker并没有什么优势,但是docker想把其容器的广泛使用的优势在caas中延续,目前看来并不容易。容器的主要用户还是个人用户、开发者用户、运维用户,而caas是企业系统,二者目标客户不同、技术要求不同。
随着这个生态的演进,docker容器会更多的用于开发、测试环境,而runc在各个caas厂商的推动下会在生产环境得到广泛的应用。
k8s目前基本只支持runc容器,对于docker超出其容器抽象层之外的功能,一概不支持。同样,mesos也通过其unified containerizer只支持runc容器,目前还支持docker,但是未来的规划是只支持unified containerizer。cf也通过garden只支持runc,不支持docker超出runc之外的功能。
2、runc生态的快速发展
由于docker的消极抵制,runc的发展好像并不为人所知,但是runc的发展还是很快的,runc本身就简单,通过版本的持续的迭代更新,目前已经达到生产可用,而且主流的paas/caas纷纷采用。docker也从1.11开始内置runc容器运行时。
除了runc本身的发展,runc的生态圈也在快速发展,这个生态圈就脱离了的docker。比如最近的riddler,就是一个把docker容器转换为runc镜像。
详见https://github.com/jfrazelle/riddler。
三、你还只用docker吗?
docker作为目前最热的容器开源项目,受到广泛的追捧。但是也要清醒地看到docker和容器生态圈的种种争斗,docker通过注册商标和在docker中内嵌容器集群管理,挤压生态圈其他公司的生存空间,而受到生态圈联盟以runc和相应的技术来制约docker。
如果你是开发测试用docker,那么基本不受影响,可以继续,这也是很多公司对docker的定位。如果你是生产系统采用docker(包括swarm),你就要注意,如果是你自己定制开发基于docker/swarm的caas(container as a service),那问题也不大,出现漏洞或是定制可以自己打补丁,但是要意识到你的补丁不一定能合并到docker的主干版本。如果是你采用的是第三方给你定制的基于docker和swarm的caas,你就一定要当心了,他们针对docker做的定制要合并到docker的后续版本有相当的难度,因为对于docker的补丁定制合并,除了docker公司其他公司几乎是没有什么控制力度的,还包括后向兼容性问题。
作为用户或是容器生态圈的创业公司,不能一棵树上吊死,如果在容器层面只考虑docker,而不考虑runc,可能会和caas/paas生态圈的标准越来越远,未来和caas/paas的标准容器差异越来越大,主流的caas/paas厂商和技术,如k8s/mesos/cloudfoundry均不再支持docker容器超越runc之外的功能,而只支持插件对runc功能的扩展。
业界更普遍的定位是docker用于开发测试环境,而runc用于生产环境,所以对于要在生产环境采用容器技术的,一定要研究runc。
作为容器创业公司,很多是在docker的风口成立的,但是由于docker一家独大和docker注册商标的法务问题,可能还没有在风口起飞。应当可以考虑在oci/runc的生态圈进行相关技术的发展,oci/runc的生态圈受到实力强大的几家公司的强力支持,如google、cf基金会、pivotal、redhat、mesos、coreos等。而且runc的生态圈还刚刚起步,还有很大的发展空间。而且作为技术创新,对于技术的前瞻性判断非常重要,方向判断正确,一路辛苦是披荆斩棘,方向判断错误,一路辛苦也是前程堪忧。
国内的公司对runc的贡献度越来越高,特别是华为,可能是国内公司中对runc贡献最大的。还有easystack、南大索芙特等的贡献,反倒是一些著名的docker创业公司看不到对runc的贡献。这一方面反应了华为、easystack技术眼光和对社区的贡献,另外也反映了为什么华为和easystack在商业上也更成功一些。
四、对一些问题的提前答复
1、runc也是docker的,用docker和用runc不是一样的吗?
docker对runc有重大的贡献,runc的早期也是基于dockerlibcontainer,但是runc在oci下独立发展,有贡献的厂商远远不止docker。在runc项目后,在oci的推动下,各个厂商积极贡献,docker的代码贡献并不占主导,更谈不上主要是docker在维护,更准确的说docker是runc的重要维护力量之一。
如下图,是git上runc的代码贡献者排名:
前10个贡献者中,docker只占2位,不得不提国内的公司华为代码贡献排名是相当的靠前。而且runc的代码贡献者超过100人。
除了k8s/mesos/cloudfoundry支持runc容器运行时,docker的容器从1.11开始也内置runc作为容器运行时,说明runc受到最为广泛的支持。
而k8s/mesos/cloudfoundry明确表示在容器抽象层不再支持docker超越runc之外的功能。
runc属于oci,不再受docker注册商标的影响,对runc的代码贡献不再受限于docker。
用runc相当于给你一个干净简单的容器运行时,用docker相当于不管你要不要,强塞给你一堆可能你不想用的东西。
2、在docker如日中天的时候这么说是哗众取宠
docker现在是如日中天,但是3年前也是刚起步,也许可以说runc就是3年前的docker。docker由于docker公司自身的商业特征,对容器生态圈其他公司的生存空间的挤压,已经造成了容器生态圈的裂变。
“风起于青萍之末”,如日中天的时候可能就是走向下坡路的开始。docker一家和其他caas生态圈分裂,这条路注定是不平坦的。
3、黑docker黑出翔来了
黑docker的资料很多,所有资料都有出处,有参考内容链接,详见后面的引用。
docker已经被布道师们说成”无所不能”,稍微有几个不能,我觉得大家还是能区别得出来。
4、runc是没人管的孩子
runc的自身发展远不如docker那么有名气,因为runc本身就是一个很小的容器运行时,不是针对开发者的,开发者往往是通过docker接触到runc,所以runc的受众远比docker要少。
但是对于caas项目来说,k8s/mesos/cloudfoundry往往就是基于runc容器运行时。
runc的社区也很活跃,除了runc本身的更新很快,各大caas/paas生态圈如google/pivotal/redhat/华为/coreos等都有专人在贡献代码。
runc相应的生态空间也在活跃,也有不同的项目在进行中。
runc是caas/paas/oci等生态圈共同的孩子,不是没人看的孩子。
业界也有一些人持这个观点。其实,标准的价值是常识,当然总会有反常识的言论出来。没有标准就没有合力,没有合力哪来的发展。如果docker公司把闭源,那可以没有标准。既然是开源,又想要生态圈的其他公司和力量做贡献,就要让大家有合力,就要让大家在标准的基础做贡献,而不是把生态圈的其他公司当作免费打工的。
五、总结和展望
docker和caas生态圈在容器上的分裂已经是现在进行时了,虽然大家都没有明说。这也将是容器和caas生态圈重要转折事件。让我们来看看目前正在发生的和在未来一年中很有可能发生的事情:
cloud foundry率先采用runc作为容器运行时,而且刚刚做了一个25万个容器集群的测试,https://www.cloudfoundry.org/cloud-foundry-approaching-250000-containers/ 验证了paas+runc的大规模集群的支持。
k8s的cri-o也会尽快发布,等cri-o成熟以后,内置的容器运行时就应当是runc,而不再是docker了。
mesos的unified containerizer 也应当会在1年之内成熟,随后内置的容器应当也是runc,而不再是docker。
在docker被科普以后,客户更关注的是caas而不是容器,再给客户去科普docker体现不出容器创业公司的价值。
一些不适合容器的docker应用场景的案例会被证伪,在docker和容器鲜为人知的时候,各种各样的docker案例层出不穷,包括一些明显和常识有违的案例,比如交易系统采用docker, 交易极严格的延时的要求不适合docker。有的是故意混淆概念,交易本身不在docker容器中,交易系统相关的一些模块在docker中,为了突出宣传效果,说交易系统采用docker。
docker创业公司分化,越来越多的容器创业公司给别人介绍自己的时候会说我们是k8s初创公司(或我们是mesos创业公司),不是docker创业公司,强调自己是caas厂商,突出自己不是docker厂商。当然,也有纯docker的创业公司,但优势会变成劣势,毕竟在caas领域,docker没有优势。
docker在容器失去了k8s/mesos/cloudfoundry的支持之后,会更专注于swarm,和caas的其他厂商的竞争将更直接,但是docker公司一贯的对企业生产环境特性的不在乎,swarm很难对其他caas形成竞争优势。
runc的生态圈将越来越丰富,第一个就是把docker镜像转换为runc标准镜像(这个已经有了),其次就是各种各样的插件和runc可以交互,中间还可以衍生出各种插件的功能,如即插即用(动态性)、自动发现之内的。
原文发布时间为:2016-11-29
本文来自云栖社区合作伙伴dbaplus