Docker 的未来

引子

老实讲,容器技术会是今后很多年系统层面最重要的方向之一。与大数据不一样的是,容器或者说 namespace 是构建技术大厦本身最基础的一环,而非像大数据一样需要先天的条件支持,任何一家公司在未来的发展中或多或少都会接触或者使用它。但是对于 Docker 本身,我认为它没有未来。

追溯最早的时候,Docker 的发家本身是偶然也可以说是必然。从技术层面来讲 namespace 技术的成熟使得近似于《三体》中质子展开二维平面的进程展开行为变得有理有据。受限于繁杂的理念和反人类的工具集,在工程成本上如果大规模使用这类技术成本上确实不如传统运维层面的背锅大法。就像协程的概念早在计算机黄金70年代就已经提出,但真正大规模进入工程生产级别也就是最近10年。随着主流语言开始推崇「服务化」之后,混布带来的资源竞争,繁杂的部署方案,不可控的 down 机时间随着服务的拆分变得越来越繁琐。一旦人力/机器成本曲线到达某个拐点之后,这个尘封的技术就被推到前台来。

而 Docker 是当时唯一一个在产品层面把 ns 相关工具和技术统一起来并且提供了便捷 API 的东西,使得原本高大上像魔法一样的 ns 操控术一下子简单了起来。把 SA 从反人类的运维脚本中解脱出来,让 RD 可以更简单的交付。对中小公司而言在省去了 SA 成本的情况下 SLA 不至于太差(因为响应速度快了),对大公司而言提高了持续迭代的效率,显著的降低了技术成本(因为机器负载率高了)。那么一直到这个时候打止,Docker 依然很美。

然而在资本世界,没有永远的朋友,只有数不尽的敌人。技术界的开源产品,大多数以 .io 什么的奇葩域名结尾,而 Docker,是 .com 。于是,在资本的涌动下,我们看到了大力支持早期 Docker 的 Ubuntu 被抛弃,看到了 coreos google apache 等容器界早期大力支持者和 Docker 自身貌合神离最后到分道扬镳,甚至连一份可靠的 OCI/OCP 标准都拿不出来。为什么?

从我的角度来说,纯容器引擎的层面来看,Docker 已经到头了。无论再怎么包装,Docker 终究是 ns 魔法的一种变体,上限就那么高,而 ns 技术本身又已经很成熟。ns 没有的,Docker 自然也不会有,比如 user namespace(当然因为现在 user namespace 已经 release, docker 很快也加上了,虽然限制重重)。但以 com 为结尾的公司肯定要以盈利作为自己最重要的目标,仅仅一个容器引擎是没有钱途的,也是没有门槛的,所以就开始上演了这 1~2 年以来各种层出不穷的 feature 或者说是断人财路的手段。

Docker 的野望

Docker 公司的目的是什么我不清楚,但我可以肯定的说他们绝对不想只做一个引擎组件。平台,工程技术界最后的边疆,你说他们没想法,那我肯定是不信的。

所以我们看到,当你要用容器需要网络支持的时候,他们一只脚迈入了 overlay SDN 的领域,至于转发平面靠不靠谱,数据平面好不好,甚至能不能灵活的设置子网,并不 care。我们在抱怨早期日志处理如何困难的时候,他们开始开发 syslog,awslogs,spluck 等可以接入商业日志系统的 driver,至于大量日志产生的时候会不会内存泄露,日志吐出占用率高不高这种问题,那都是小事。我们在抱怨早期 Docker 安装不方便,对内核对系统都有要求时,docker-machine 应声而出,至于能不能 integrate 现有的基础设施,那不在考虑之中。

等等这些,都还没有触动巨头们的利益,直到 docker swarm。

swarm 刚出的时候其实很多人都不看好的,我就是其中一个。诚然用上容器技术以后,少了的是运维脚本层面上的活,多的了却是在部署调度上操的心。容器的调度和编排是整个容器领域最重要的一环,是真正能打通技术 workflow 的一环把成本控制下来的一环。所以我们可以看到 Google 家的 borg 论文,可以看到 mesos 推出的 marathon,甚至可以看到我们这类早期容器使用者自己写调度工程师。经过一段时间以后,无论是 k8s 还是 mesos,至少在工程领域是经过了考验的,我们真的需要另一个所谓 native 的调度编排工具吗?

我自己的观点来看,对于有实力的公司,调度编排本身不是问题。无论是自己写还是拿现有的改,均绕不开二(一)次开发的成本,这个成本主要体现在跟现有平台工作流的结合上。不是说你下一个 k8s 就能跑的了,如果我之前用的是 openstack 呢,要不要改造,要不要保证上层接口不变的情况下接入,这都是成本。对于没有实力的公司,大多数处于创业阶段,也就拿容器当虚拟机跑了,随手一丢能快速重启就行,谁还需要调度和编排?

因此 docker swarm 的路不好走 ,也确实没走得很好。论历史不如 mesos 为首的 apache 工具链,论身份不如 k8s 号称开源版的 borg,论架构呃,早期那个单主的架构可靠性真不咋滴。以我的观察来说,唯一知道以 swarm 为主的恰好是前 Leader 洪教授带领的宜信平台团队自行开发的 lain,其他的基本全是 k8s/mesos。然后,docker 在 daemon 中集成了它,而且是在大版本的发布中直接整合了它。

恩,一个容器引擎突然就能开始编排和部署了,这叫 k8s/mesos 等还怎么活。KISS 原则就像被丢到了历史的垃圾堆,完全被 Docker 的开发者给忽视。一个新司机上路再也不用负担更多的心智成本在第三方的开源编排部署系统上,但这是好事吗?让最重要的基础设施傻瓜化一定就是最好的选择?那一天,业内终于回想起了,曾经一度被360全家桶所支配的恐怖,还有那种没选择权的屈辱。

Docker 的阿格硫斯之踵

如果只是到此为止,Docker 公司的策略不可谓不精明。先是抛出一个最小化的引擎搅动沉寂已久的传统平台研发圈,再抛出一个编排和部署的概念,让第三方把路踩平,最后直接集成自己的方案,完整的统一整个容器生存周期。就目前的容器圈来说,事实标准就是 docker。无论是 rocket 也好,还是 system-nspawn 也好,均构成不了太多的威胁。至于各怀鬼胎的 OCI/OCP,天呐你真高。

但是 Docker.com 不是 Google.com,前者在工程师的配置以及项目质量管控上和后者中间差了 2^1024 个 Facebook.com。

早期 Docker 版本仅限于 Ubuntu 的支持,CentOS 关是折腾内核就能吓走一批人。多年的经验总结出来的偶数定律精确的总结了 docker 这些年来所带来的大坑,1.4 版本的设备释放失败导致 fd 泄露,1.6 版本日志 API 的内存泄露还有 daemon crash,1.8 发布的第二天就紧急发布了 1.8.1 用于重大 bug 修复,1.10 的 stats 接口没数据输出等,满满的都是系统工程师的血与泪。更不用说到现在还没解决的主父进程树结构在 daemon 意外关闭后残留容器无法回收或者恢复的这种恶心问题。在最核心的 daemon 尚且如此的情况下,又要把编排和部署整合进去,把原本旁路控制的系统和最核心的容器引擎耦合,一旦任何一方产生不可预知的行为,都将导致整个系统的崩塌。

从我自己来说,docker daemon 的每次升级都特别的别扭。举个例子,早期我们都是通过扒 docker 代码调用内部 public 接口获取 container stats,1.5 的版本提供了一个 stats 接口。我们看看当时这个接口能做啥,1s 返回一次 container stats,不允许中途退出,不允许只获取一组数据口退出,只能等待 container 自己 stop 后才行。试问那个系统工程师的东西会保持 1s 的频率去不断的 pull 一组 stats 数据,而且有多少个容器你就得默默的开多少个「线程」一直的挂在那里去轮询!好吧,既然这扇门有跟没有似的,那我继续我们之前的调用内部接口方案呗。不好意思,您要的接口已不存在。恩是的,至于向下兼容这是,似乎 Docker 的开发者从没想过。

所以我一直认为,docker daemon 本身的核心功能及代码质量远不能让人放心的去集成其他的功能和服务。每次 daemon 升级需要近似于停机以及冒着彻底损失这些 container 数据的风险,如果这时候编排和部署也在发生怎么办,停 daemon 后集群策略能不能预知,这都没有经过长时间工程的检验。诚然 KISS 原则会使得服务繁杂,甚至会有些 ugly,但是适当的解耦和透明化对这种一枯俱枯的平台层面基础设施来说至少会让人安心不少。平台层面的优美,远不如可靠性来得重要。

Docker 的未来

一旦有适当的利润,资本就胆大起来。技术型的企业要在市场中活下去不是靠开源,也不是靠 to C 而是得靠 to Business。Business 的时候拿出来的一大半都是开源组件,这生意就没法谈了。所以 engine 稳不稳定可不可靠,谁关心,用户需要的是一揽子解决方案,需要是那种「变幻莫测」的 feature,需要的那种可以说出去的噱头,至于你们这种拿着社区版自己造轮子免费用的死活,关我屁事。

但是 Google 也好, CoreOS 也好,RedHat 也好,也是 .com 的公司呀。断人财路无异于杀人父母,可见的未来里面 Docker 公司的策略依旧会是破坏向后的兼容性,因为他们对 docker engine 本身的定位就是产品而非社区自有的服务组件,他们现在是这个圈子里面的「苹果」,虽然他们是借住社区力量野蛮生长起来的。于是我们看到了 HN 上已经开始有人讨论「What I found wrong in Docker 1.12」,其中阐述了 1.12 版发布以来一部分的观点,越来越不可控的可靠性,向后兼容性保证,版本的管理等等。于是原本水面下巨头之间的博弈慢慢的浮出水面,这篇报道「A Docker Fork: Talk of a Split Is Now on the Table」就差直接说再这么下去迟早我们要自己 fork 了。越来越多的证据表明,如此以往类似于 Node 分裂成 io.js 的事件,也将发生在容器圈。

虽然这些公司打着的都是「斩杀」恶龙的旗号,虽然我们不知道他们会不会成为新的恶龙,虽然大家心知肚明这就是 Business is Business,但我自己肯定是赞成在 OCI 或者超越 OCI 的标准下,社区应该有一个无状态,可靠的,适配多种目标环境的,简单的容器引擎,而不是现在这种大杂烩,使得我们在使用过程中如履薄冰,也没有足够的自主权。

换句话来说,以现在 OCI 被一家强势公司挟持成了自家产品的一个分支,这算哪门子标准,还不分手留着过年呢?

创业预警

多说一句的是,目前炒得火热的容器云创业其实我是不看好的。就像上面所说,技术的产品一定要 to Business 才有活路。这里就会产生一个悖论,技术不够的团队/公司往往会简化整个的架构,也没有足够的够消费力支撑起容器型创业公司的收益。那么有一定能力的团队/公司往往会倾向于自主可以把控的东西,会不会选择容器云是得打个疑问号的。

况且以现有容器云所基于的 Docker 容器化技术而言,多租户的前提下隔离性和可靠性尚不能完全保证,传统 VM 再套一层 docker 的行为又更像是脱了裤子放屁。尤其是在的 Docker 公司本身推行的容器云服务的情况下,这些更像「异端」公司能有多「光明」的前景,我自己的观点是谨慎看空。假如主做私有云的情况下,那么就回到了上面所说的能理解这个东西好处的公司,往往就已经有自己的人可以做这方面的事了。另外从服务器规模效应来看,目前传统的 IaaS 服务公司如 AWS 如阿里云依然有着无与伦比的边际成本和经过市场检验过的基础设施,在议价能力上有着先天性的优势,那么他们也做容器服务怎么办,你能保证同等单位价格情况下提供更好的网络,更好的隔离,更稳定的服务,更多的集成组件么?

那么这一行就是完全的巨头博弈了么?其实也不。在公司层面中小型手工作坊式的团队一旦过了「怎么活下去」这个阶段以后,必然会希望技术的「舞台」更大更强更正规,在有能力的情况下容器技术会以更低的成本带来生产力的提升和流程的正规化,这个过程是真金白银的蜕变。即便在公有云上,也有类似于 hyper 这样的公司力图解决容器技术目前在多租户环境下的弱点,提供容器本身的便捷性同时避免与 VM 大厂们的直接竞争,在新的战场上力求与巨头们分口汤喝。

最后,我期望一个超越 OCI 标准的实现,至少 Docker.com 规划的未来我并不认同。对于想走平台层面这条路的人来说,脚踏实地的跟着一家蜕变期的公司成长,远比追逐风口上猪来得实在。