作者介绍
周晖,Pivotal大中国区云计算首席架构师,有丰富的PaaS云实际建设经验,负责过国内某知名银行已经生产上线一年的PaaS云的架构设计和部分功能的实现,参与过某超算PaaS、某超市电商PaaS、某电力PaaS等项目的建设。
一、从一场容器的撕逼战开始说起
从2016年7月底开始,GoogleKubernetes布道师KelseyHightower和Docker的CTOSolomonHykes在Twitter上发生了一场撕逼大战,主题是要不要用RunC或其他容器来取代Docker引擎以及OCI的意义。
首先是Google的Kelsey挑事,说:“很多平台都可以跑Docker镜像,已经不再需要DockerDaemon了。哪个会成功呢?”
DockerCTOSolomon马上接招:“其他平台跑Docker镜像是假的,其中只有90%能正常工作,其余10%则随时可能会出问题。而且Docker还在演进中。”“所以嘛,声称‘可以跑Docker镜像’的都是在撒谎。”
KelseyHightower反讽:“好吧,那我们就没必要再提支持Docker了。我们实际支持的只是Docker的容器格式”,“Docker拥有创建和分发镜像的最佳工作流,而运行时,还是留给它的竞争者们吧。”
所罗门继续强调Docker的不兼容性:“这些都是不完整的、不兼容的支持”,“他们也并不支持镜像格式,镜像的很多信息都会丢失”。
后来,所罗门急眼了,说“OCI就是个伪标准”。
此言一出,惊诧四方,因为OCI有50多家厂商参与,而且Docker还是重要贡献者,有说“标准不是一个人可以决定对错的”,有反讽的“我相信工程师们乐于听到他们创始人说他们做的工作是假货”。
K8s的老大TimHockin直接就说“不爽你就走,不要假装参与”。
所罗门不得不改口说“OCI标准的初衷是好的,只可惜扩展太早,我不认同就得走?”
有人随即反驳“只有你一个人说扩展的太早,这是明显的利益投射”。
所罗门还嘴硬“就因为我是唯一的不认同者,那我就必须离开?”
Kelsey随后则直点主题,“有两个问题在台面上,一是容器需不需要标准化,二是需不需要由Docker来领导这个标准化的工作?”
Kelsey再以嘲讽的口吻自问自答“如果是Docker来回答这些问题,对第一个肯定是说不,那干脆对第二个问题也同样说不吧,这可不是对和错的问题”。
因为事关OCI,Docker现在这么鄙视RunC,OCI不得点出Docker你也是参与者就别闹了,“Docker参与在OCI运行时和镜像规范,也参与了每周的开发会议”。
Kelsey乘胜追击,代表业界吐了个槽,“我一直相信Docker会给容器带来很多,但是我真的担心一个人想控制的太多”。Docker公司的控制欲早成为人们的吐槽点,什么都想做,把整个生态圈其他的参与者逼到墙角去了。
看业界大佬撕逼,感觉和咋人民群众撕逼没太大差别。所罗门的撕逼技巧明显略逊一筹,有点像祥林嫂反复说“其他容器就是和Docker不兼容,包括RunC”,但是没说出个哪里不兼容的道道。
二、容器撕逼之争反应了容器生态面临的问题
我们来总结这次著名的撕逼事件的来龙去脉,这会成为容器界一个关键的历史转折事件。容器之争始实际上是很早之前就起源于Docker生态面临的问题。
1、Docker商标的注册围剿了容器生态圈
从表面上看,是容器标准之争,其实,反应的是赤裸裸的利益问题。Docker从容器开始,在获得社区的热烈响应之后,就进入了圈地过程,而且第一招圈地就非常凶悍,把公司从dotCloud改名为Docker,然后注册Docker商标,商标意味着当其他公司使用未经Docker社区许可的补丁、代码或软件包的时候时可能面临法律责任。这种情况下,一个公司可能因为补丁尚未经过Docker公司许可,抑或尚未被合并到项目中,而不能为客户提供技术支持。
这不只是法务上的圈地,对于很多采用Docker名字的,Docker公司给予了实际行动—口头警告(谁叫Docker是人家注册的名字呢,就好比weibo.com就是微博),包括你建一个群名不加修饰限定的叫Docker,或是你要写本书,不加修饰的叫DockerXXX,都容易受到Docker的警告。从法务上看这确实也属于侵权,就看Docker要不要告你。
其后果就是第三方Docker生态厂商被迫忍受Docker公司任何对该开源项目作出的决定,在问题出现的时候等待Docker公司的补丁。最好的结果与Docker达成某种协议,由Docker公司来保证提供稳定的发行版本。那Docker的生态公司就沦为Docker公司的代理商了。
2、Docker携容器引擎优势进入容器集群管理,挤压了容器生态圈的其他厂商生存空间
如果只是口头撕逼,那大伙儿看看热闹就可以了,事实上这涉及到巨大的利益和整体生态环境的分歧。
在Docker获得广泛关注以后,就利用Docker容器的广泛性优势来挤压生态圈其他伙伴的生存空间。直接把Swarm内置在Docker中。和当年的Microsoft通过Windows捆绑IE来打击NetScape有异曲同工之妙。
Docker公司原来只在容器领域发展,K8s/Mesos等做容器集群管理,属于CaaS(ContainerasaService),相互补充,互不竞争。等Docker容器被广泛关注以后,Docker进入容器编排市场,收购了相关的技术以后推出Swarm的容器集群管理,从容器进入CaaS市场。2016年7月发布的Docker1.12把Swarm内置到Docker中去了,DockerSwarm作为容器集群管理软件,内置在Docker中,几乎就是Windows捆绑浏览器IE的模式,这就是用不平等的市场优势打击了Google的K8s和Mesos等,Google也不是吃素的,所以7月底马上就是和DockerCTO口头开撕。
对于Docker生态圈的集群管理软件K8s和Mesos等来说,不但是不平等的竞争,最关键的是在容器生态圈最能带来商业价值的就是容器集群管理,单单容器本身并没有太多的商业价值,容器没有集群管理是很难进入企业运行环境的。因为容器的直接商业价值并不大,CaaS厂商也没有自己做容器。容器用于生产系统,就必须有容器的集群管理,而K8s和Mesos已经进入了这个商业领域并且取得了一定的优势。现在Docker进入这个领域,就直接和容器集群管理的公司竞争,但Docker又是必须进入这个领域,如果不进入这个领域,很难取得商业成功,Docker本身又经过多轮风投,风投给Docker带来了巨大的盈利压力,如果久久不能盈利,那风头的脸色不会那么好看了。
如果是公平竞争还好,比如Docker单独发布Swarm的Docker集群管理,但是Docker直接把Swarm内置到Docker中去,安装部署Docker就带了Swarm,而Swarm的很多功能和K8s和Mesos是重叠的,K8s和Mesos再用Docker就显得功能有大量重叠,而且带来了系统的复杂性和不稳定性。
三、Docker的问题——业界对Docker的吐槽
在Google和Docker口水战之后,业界对Docker的吐槽越来越多,主要包括以下几点:
1、Docker向后兼容性问题
Docker被业界诟病最多的就是后向兼容性,Docker的新版本更关注的是革新性,而不是兼容性,但是,对于一个生产系统来说,后向兼容性至关重要,没有后向兼容性,意味着每次Docker升级都带来巨大的风险。
这也和Docker的企业文化有关,Docker更倾向于采纳新技术,实现突破性的功能,这是典型的初创公司的企业文化,不断的追加新功能,而不考虑企业级特性,更不考虑后向兼容的束缚。这个好处是能在个人粉丝中取得共鸣,这也是Docker快速流行的一个重要原因。任何特征都可能是双刃剑,这种企业文化并不适合企业级,不考虑生产运行的可用性,对企业级应用来说可能是灾难性的。
我们看看业界人士是怎么说的:“Docker不断地破坏向后的兼容性”,RackN公司的CEORobHirschfeld说。RackN公司的应用程序生命周期管理平台同时使用和提供了Docker组件,因此对后端的改动将会对其支持的客户的业务造成影响。
“Docker将DockerEngine用作一个产品,而不是一个社区用来构建自有服务的组件”,Hirschfeld指责道。这种基于产品的策略意味着使用者被逼着在Docker发布新的革新特性或者合并新的组件(如Swarm)的时候去修复其破坏的向后兼容的问题。
“尽管我们会使用这些发布的特性,然而这些改动会带来一系列与稳定性、版本、迁移和后端兼容相关的问题”。
BobWise,一名三星SDS云工程师,也同样呼吁Docker放慢其容器创新的脚步,该公司同样提供了基于云的容器相关支持服务。
“如果你的团队在深度使用Kubernetes、Mesos或CloudFoundry,你需要一个稳定、简单、无奇的容器实现方案,仅有最少的基本功能,由社区协商镜像的创建、命名和发布”,Wise的一篇博客中写道。“你需要使用每个都人都在使用的一个相同的、简单的、无奇的容器实现方案。作为一个社区,我们需要放缓对于基本构建组件的变更速度。唯有稳定性才能让构建其上的系统蓬勃发展。”
2、Docker容器在企业级方面还有待提高
Docker虽然一直宣称ProductionReady,但是在实际的生产系统中同样受到不少诟病。
看看业界人士的说法:
Apcera技术产品经理PhillipTribble在个人博客中,以一种外交辞令的口吻,让Docker不要再把其新推出的特性鼓吹成一个完工的企业级可用的产品。Tribble写道:“让互联网或者大会充斥着营销材料,宣扬各种令人振奋的新特性,但实际上却不如所说那样能用,不是一个明智的做法”,Apcera的商业模式一部分是基于提供Docker容器的支持。
Tribble的帖子引发了其他人在HackerNews上表达他们的Docker经历,包括一些新版本带来的让人伤心的bug。一位读者谈到一天中启动70,000到90,000个容器,约9%左右的会因为“各种Dockerbug”遇到问题,这个比例最近的一次升级后下降到了4%。
但也有一些人在称赞Docker的稳定性,“我们一直在生产中使用Docker约3年了,还没有发现什么大的问题”,另一外读者评论说,“它将一些很炫的Linux内核特性用简洁的方式封装了起来”。
当然也有不少Docker的支持者认为Docker公司的软件是稳定的。同一个产品,在不同的客户有截然相反的反应说明有的用的好,有的用的碰到不少问题,在不同的环境下缺乏一致性,这也是企业生产系统的大忌。
3、Docker捞过界了,越过了红帽的操作系统界限?
哪些功能应该有Docker来实现,哪些功能应该由底层操作系统或者技术栈中的其他组件来负责处理?
在今年的很多会议上,包括LinuxConNorthAmerica2016,红帽工程师DanWalsh说红帽陷入了困境,一方面客户越来越多的使用systemd来初始化Linux系统,而另一方面Docker似乎不愿使用systemd,取而代之使用DockerDaemon来提供初始化,服务激活,安全和容器日志的相关功能。
“在过去的三年里,我们一直试图使systemd和Docker更好的整合,而我却发现,两个领导人都非常强烈的坚持己见”,Walsh说,两个领导人指Hykes和systemd的创造者-LennartPoettering
“所以,当机器的时候,谁来负责启动系统服务,是systemd还是Docker?”Walsh问到。一个拙劣的系统实现可能会导致systemd和Docker互相冲突。
红帽为自己的客户维护着自己的Docker版本分支,红帽分支中的补丁Docker有一天可能会合并,或者永远不。红帽也冒着巨大的风险,红帽的客户也冒着巨大的风险。所以红帽对Docker的支持其实远不如Ubuntu,因为Docker已经侵入到OS的领域了。
即使是面对以上种种吐槽,Docker也不打算折中一下,甚至也不打算照顾这些意见,而是继续我行我素。
四、容器生态圈集群管理厂商的应对
——不用Docker,把容器引擎拆解重组
撕逼只是矛盾爆发的阶段总结,后面就开始进入实质性的对抗阶段了。容器生态圈的集群管理厂商如Google/Mesos也不是吓大的,快要被Docker断了财路———“人为财死鸟为食亡”,其反应也直取Docker命门——在其CaaS中废弃Docker,对容器进行抽象,用谁的容器都可以。容器运行时不再用Docker,而直接采用RunC,容器扩展功能通过插件来实现,基本就是全抛弃Docker了,这对Docker来说几乎是生死之战。
其实,容器技术本身的壁垒不高,Docker2013年一开始也就是几十人的开发队伍,到现在也只有200多人,各大厂商一直没有重视这一块,因为单单容器的商业价值比较低。真正要投入做容器,也只是分分钟的事情,只不过Docker已经在容器领域形成了气候,所以要走些变通的曲折路线。
各大厂商一起做个RunC,大家再只用RunC还是轻而易举的。
我们再来看容器最主要的两个的技术来源:
Namespace—来源于IBM
cGroup—-来源于Google
其他的容器核心技术都是Linux操作系统的功能,容器的核心技术是和Linux操作系统密切相关的,Docker本身在容器核心并没有什么贡献,NameSpace和cGroup都不是Docker的,也和Docker无关。Docker也不是最早用容器技术的,CloudFoundry比Docker更早把容器用于PaaS。
所以容器生态圈的公司撇开Docker做一个容器标准并不是什么难事。
我们再从时间线来梳理这个撕逼事件,让大家更直观的理解:
1、提前铺垫:先通过RunC把容器运行时分离出Docker
2012年,随着CloudFoundry的PaaS率先引入了容器技术,容器技术发展的愈发火热,特别是Docker成为流行技术,形成了广泛的生态圈,由于Docker一贯的控制欲,让生态圈的其他大小伙伴难以参与,为破解这种状况。Google先是支持CoreOS打造了Rocket容器,在Rocket和CF容器Garden的竞争压力下,Docker终于同意容器标准化—-RunC项目成立,通过RunC对容器运行时进行标准化。
于是容器生态圈终于达到了拆解Docker技术堆栈第一个小目标—通过RunC把容器运行时独立于Docker之外。在2015年6月成立OCI(OpenContainerInitiative)组织,挂在Linux基金会旗下。旨在围绕容器格式和运行时制定一个开放的工业化标准。该组织超过50家大小成员,包括谷歌、Pivotal、Docker、CoreOS、微软、亚马逊、华为等一系列云计算厂商,按照该开放容器格式标准(OCF,OpenContainerFormat)制定的一种具体实现,当然Docker是RunC的重要贡献者。
OCI对Docker意味着什么,Docker不是不清楚,知道RunC是来抢食的,除了会削弱自己的优势,也还会被OCI标准束缚住,限制自己的发挥,所以Docker对OCI是消极抵制,但是无法和整个生态圈抗衡,不是不接受OCI和RunC。
面对Google、RedHat或者Microsoft这样的大公司,不管从技术实力还是财务实力,以及政治关系处理上,Docker应该都很难占到太多便宜。但是技术大势所趋,Docker也无法抗拒。
2、RunC容器格式标准是什么?
制定容器格式标准的宗旨概括来说就是不受上层结构的绑定,如特定的客户端、编排栈等,同时也不受特定的供应商或项目的绑定,即不限于某种特定操作系统、硬件、CPU架构、公有云等。
最核心,是通过格式标准化来脱离Docker,有利于CaaS生态圈的公司各自发展,但是在标准层面汇聚。
3、RunC容器标准化宗旨
标准化容器的宗旨具体分为如下五条。
操作标准化:容器的标准化操作包括使用标准容器感觉创建、启动、停止容器,使用标准文件系统工具复制和创建容器快照,使用标准化网络工具进行下载和上传。
内容无关:内容无关指不管针对的具体容器内容是什么,容器标准操作执行后都能产生同样的效果。如容器可以用同样的方式上传、启动,不管是php应用还是mysql数据库服务。
基础设施无关:无论是个人的笔记本电脑还是AWSS3,亦或是Openstack,或者其他基础设施,都应该对支持容器的各项操作。
为自动化量身定制:制定容器统一标准,是的操作内容无关化、平台无关化的根本目的之一,就是为了可以使容器操作全平台自动化。
工业级交付:制定容器标准一大目标,就是使软件分发可以达到工业级交付成为现实。
RunC标准化是瞄准工业级交付和运行时的,和Docker定位不一样。各个CaaS/PaaS生态厂商需要一个标准的容器运行时,然后围绕着这个标准运行时各自发挥自己的技术优势,做编排的、做集群管理的、做资源调度等等,形成真正的容器生态圈。
4、第一步:虚张声势扬言对Docker容器另起分支,废弃Docker公司对Docker的独一控制权
在和Docker撕逼之后,引起了业界的集体吐槽,然后Google进入第一步:虚张声势,先来个大杀招吓唬Docker——尝试分支开源Docker来废除Docker公司对Docker容器的独家控制权。
先是Google方放出风声,要对开源的DockerEngine重起炉灶—分支出一个容器,马上在业界引起巨大的波澜。
“在诸多正在考虑的选项之中,包括可能会将整个开源的DockerEngine一起重起炉灶(fork)。据一些接近讨论的人士透露,相关代表来自RedHat、Google、CoreOS、华为和两家大量使用Docker的客户。”
随后大家对Docker的代码库稳定性不足表达了各自的忧虑,因为这可能会在生产环境下基于Docker构建附加服务或者向客户提供技术支持的时候招致各种麻烦。在表达各种对Docker公司在DockerEngine上管理的失望之后,没有得到Docker的正面响应,相当多的技术专家和公司是支持分支的。因为Docker也不是吓大的,对种种指责不予理会。
但是,也有很强的声音担心Docker从此支离破碎:
“目前发生的这件事情,如果处理不得当,会让让容器生态系统支零破碎,并导致单个的容器再无可能适配多种目标运行时环境。”一位HackerNews上的观察员指出。
鉴于直接分支对整个生态会产生不可预知的影响,属于杀敌三千自损八百的,虽然DockerCTO所罗门当初说OCI是个伪标准就是“杀敌三千自损八百”的招,但是碰到猪队友不能把自己也变成猪。直接分支停留在口头上。
5、第二步:通过RunC和插件来拆解Docker技术堆栈
在和Docker撕逼之后,引起了业界的集体吐槽,然后Google和业界进入第二步:
随着RunC标准化的发展,RunC逐步成了构建容器运行隔离环境的标准,和Libcontainer的功能类似,Libcontainer对RunC也有很大的贡献。那到底RunC和Docker是什么关系,如下图:
Docker从1.11开始就采用了右边的架构,这其实是Docker公司折中妥协的结果,因为面对Rocket和Garden的竞争,如果不支持RunC,那么在容器马上就会进入分裂竞争状态。
而OCI业界希望能够在容器的运行环境标准化,也就是构建出一个容器运行环境的这部分能标准化,在容器运行环境下不需要Docker庞杂的功能,容器运行时这部分占Docker的整体功能比重很小,所以OCI组织很快就达成的一致,发展RunC容器运行时。
所以,理解Docker和RunC的关系,你可以理解为RunC是Docker一部分,而且是构建容器隔离运行环境的一部分,而这一部分,也恰恰是CaaS的厂商所需要的,他们只需要一个生产环境下的容器环境构建,不需要容器的镜像打包等,这属于开发测试所需。
通过RunC,也基本确定了CaaS/PaaS产品如CloudFoundry/K8s/Mesos等只需要RunC这个容器生产时的运行环境,而Docker更多的用于开发测试时。
除了RunC,容器插件也是一个关键的公有技术,把容器的功能扩展和外部交互的功能插件化,而插件在开源社区相当活跃,插件主要是四类:安全认证、存储卷管理、网络、IP池。比如各个存储厂商都在开发或是已经开发了自己的存储插件。
而这些插件也可以和RunC交互,通过上面一层的集成,可以让RunC用到这些插件。而插件也基本外化了Docker的功能。
虽然Docker定义和开发了很多插件,但是插件可以各自开发。插件只要提供接口就可以容器运行时交互。不再局限于某个公司的插件。这里不得不提到K8s开发的网络插件CNM和Docker自身提供的CNI就不一样,虽然理论上是可以相互兼容,但是实际上是两套实现机制,而且CNM得到了CaaS/PaaS厂商更广泛的支持。
通过RunC和插件,把Docker容器引擎的功能进行了分拆,而且分拆的部分都有了替代品,只等下一步。
6、第三步:CaaS生态厂商通过容器抽象、RunC和插件来重组自己的容器技术堆栈
如下图是各个业界厂商对Docker容器技术堆栈的进一步分拆,然后进行组合,形成各自自己的容器堆栈。分拆不是目标,是手段,组成成自己的容器才是目标。和我们的国产化替代是不是有点类似?
首先把Docker的技术堆栈分解为容器运行时RunC、插件、容器管理进程和容器仓库。因为已经有了RunC的基础,而且插件可以公用,各个厂商只要做容器进程管理和容器镜像管理,既然是新的技术架构,各个厂商也考虑到容器的兼容性,大家很一致的做了一个模块,称为容器抽象,无论是Mesos还是K8s。有的把容器镜像也一起做在容器抽象层,有的是单独再做一个镜像管理。
看下图右边的重组后的技术架构,完全没有了Docker,也不需要Docker,但是很自然而然的取代了Docker的容器。这就是很典型的对Docker技术栈分解,先取代最核心的容器运行时RunC,再把功能外化到插件,然后再做一个容器抽象层,彻底肢解并取代了Docker。
注意红色的框架,通过RunC和插件,CaaS/PaaS业界把他们所需的容器功能从Docker中独立出来了,也就是有了RunC和插件,CaaS/PaaS完全可以不需要Docker就构建出CaaS/PaaS运行环境。
行文至此,大家应当对容器生态圈的撕逼事情的来龙去脉、各个厂商的应对、撕逼原因以及整个容器生态圈的巨大变化有个初步了解,欲知后事,且听下回分解。
文章出处:DBAplus社群(订阅号ID: dbaplus)