我与容器的缘分起源于我在 Google 内部研发容器集群管理系: Cluster Management 。谷歌内部一切皆容器,搜索、视频、大数据、内部工具等核心业务都以容器的方式运行在容器编排系统 Borg 上。 2014 年,随着公司内部的“ Ursquake ” (注: Urs 是负责基础设施的高级副总裁),我转投到了公有云 Google Cloud Platform 的建设当中。 2014 年 3 月份,在由各部门基础设计技术带头人参加的谷歌内部的云峰会中,我做为早期参与者之一加入到了 Kubernetes 的项目中。
从 2015 年回国创业至今,我亲身感受到了国内对于 Docker 的追捧热度。如今, Docker 已经迅速在国内形成了“要是不知道 Docker 都不好意思和人打招呼”的火热势态;在互联网巨头和独角兽企业中,甚有从“谁在用 Docker ”转变为“谁没用 Docker ”之势。
Caicloud 基于 Kubernetes 开源技术,力争为企业提供 Gifee ( Google ’ s Infrastructure for Everyone Else )的体验。目前已经成功落地于多家国内大型企业,其中不乏传统国有企业。在不少案例中,我们都发现一个明显的趋势:很多企业一开始受到 Docker 现象的鼓吹,认为 Docker 是万灵药,然而在自己尝试进行开发、生产使用时才发现 Docker 带来的不仅仅是“坑”,更多的是局限和对已有流程的颠覆。这里我想从我在谷歌内部使用容器,并基于容器研发大规模生产平台的经验中谈谈现有 Docker 和谷歌容器环境的差别,并通过 Caicloud 的实际案例落地经验总结下 Docker 自身所带来的一些“谎言”和误区。希望能抛砖引玉,并在产品上填补空白,实现 Gifee 。
Docker 的谎言
这里用“谎言”略有夸大其词之嫌, Docker 也确实为软件开发带来了巨大的好处。而我想表达的是人们对于 Docker 的一些常见预期在现实使用中并非像理论中那般完美。
Docker 达到了环境一致性
几乎所有的 Docker 介绍或教程中提到的前几个 Docker 带来的好处之一,必有“环境一致性”。然而这句话表述的并不准确,“环境”是一个模糊和相对的概念。 Docker 实现的是镜像内部的小环境一致性,它保证了一个应用程序在一台机器上使用 Jetty 9, 在另一台机器上也使用 Jetty 9 (通过封装软件中间件如 Jetty 9 )。然而大中型企业用户很快意识到,真正的难点在于如何保证“大环境”一致,即整个业务系统中众多容器、组件、服务之间如何配置、互联、依赖,如何保证开发、测试、生产环境能相互转化、克隆等。这些环境、配置在容器概念之上,是容器自身无法解决的,只能依赖集群层面的管理工具。
Docker 帮助了微服务
微服务与 Docker 是两个完全独立的维度,微服务所带来的好处完全不依赖于你是否使用 Docker ,同时微服务所带来的问题 Docker 也无法解决。例如,如今大家都流行将原来的巨石型应用进行微服务细粒度切分,而第一个难点就是切分的粒度。虽然不乏最佳实践和 Rule of Thumb, 但总的逻辑是切分的粒度越细,软件开发灵敏度越高。然而带来的问题是管理成本的增加:更多的模块如何进行各自的配置,更多的 API 通信、互联如何管理,更多的二进制(容器)如何发布。这些问题都是 Docker 自身不能解决的,也必须通过第三方工具来进行弥补(例如 Kubernetes 的 Pod 机制就是谷歌基于内部的经验教训设计的一个解决方案)。
Docker 实现了以应用为中心
Docker 的大火也让” App Centric ”, “ Cloud Native ”焕发了青春, Docker 确实在为实现这两者的道路上提供了便利,但 Docker 本身还远远不能和这两个词划等号。 Docker 对应用虽然进行了封装,但是应用的开发者在实践中还远无法做到只要关心到 Docker 这一层即可。首先我们还是要关注操作系统,是否有合适的内核,是否有合适的 API 支持。其实我们甚至要关心硬件,是 x86 架构还是 power pc 架构。此外,我们还需要关心引擎,是 Docker 还是 Rocket 还是 runC 。最后,开发、运维者还要关心平台,是 Kubernetes 还是 Mesos 来进行生产集群管理,并需要针对具体的底层平台做完全针对该平台的部署、配置(甚至需要修改应用、框架等)。而这些都不是应用、业务所应该关心的范畴。
Docker 实现了 Devops
Docker 有很多开发、发布敏捷性方面的亮点,然而不少企业用户认为 Docker 自身就迈向了 Devops ,而残酷的现实是他们往往在真正开始使用后很快发现 Docker 带来了额外的负担,例如基于 Docker 的发布流程应该是怎么样,应用程序打包的最佳实践应如何(如何避免打出一个上 G 的包), Docker 的镜像仓库该如何管理(如何有效利用存储空间、识别 Dockerhub 里的恶意镜像)。总之, Docker 毕竟给系统中引入了新的一层东西,业务出了问题,到底是应用的问题还是 Docker 的问题?最后( among many others ), Docker 自身主要是进程级别的,而对于复合型、集群化的场景(翻译:任何一个认真的生产场景)则需要第三方的工具和系统来补足。在机器层面,如何做到跨主机的通信、数据的迁移、跨主机的任务调度;在应用层面,如何做到用多个 Docker 镜像 /容器构造成一个复合性应用( Codis 就是一个很好的例子)。当然, Docker 的安全性也是经久不衰、流行的议题。
一个好汉三个帮
还是要说明上述的论点旨在让企业用户认识到 Docker 自身不是万灵药,但是我们也不可否认 Docker 对于软件开发、发布和计算上所带来的变革性优势。如何基于 Docker 自身的优势更上一层楼,我认为需要顺应“社会专业化分工”,让专业的人做专业的事,通过第三方工具一起打造一个完善的生态系统。
谷歌在十年间打造了三个集群管理系统: Borg 、 Omega 、 Kubernetes ,原因就是基于它领先于外界多年的容器使用经验,它清楚地意识到容器自身的局限性(只是应用运行的一个“载体”,和其他的载体诸入虚拟机、物理机在这个角度上甚至没有本质区别)。在虽有 Mesos 这一开源项目的情况下,谷歌还是在 2014 年决定大力推广 Kubernetes 项目(内部代号为 “ Project 7 ”),是出于几点深思熟虑。这些出发点也在 Kubernetes 在国外众多知名企业(如 ebay 等互联网巨头,或高盛、 Bloomberg 等金融巨头)和 Caicloud 在国内一些大型甚至传统国有企业的成功落地中得到了验证):
谷歌有着更多年的大规模生产级别容器管理经验,这里说的“大规模”是百个数据中心、百万台机器、亿万个容器,且这个“经验”既有成功也有教训。例如通过设计 Borg 我们清楚地意识到配置管理的重要性,声明性管理的重要性,为每个服务分配独立 IP 地址来避免端口冲突的重要性等。通过 Omega 也意识到了可插拔调度器的重要性,模块化系统的重要性,以及对于任务的完成时间的不可控性等。因此 Kubernetes 希望能够将谷歌内部多年容器管理的理念、经验、教训以开源项目的形式传递给大家,而这个经验是独一无二的。
另外与 Mesos 的关注点不同(资源分配), Kubernetes 是完全原生态面向服务和集群化容器应用的( Mesos 面向的是“框架”),它旨在提供更多便捷的容器管理工具、机制和功能。因此除了常见的任务调度、服务发现、健康检查和自动修复,它还提供了独特的功能,诸如容器组管理,秘密管理,服务账户管理,配置管理,守护进程管理,宠物应用管理等,都是谷歌在内部形形色色应用、业务类型管理中所提炼出来的重要功能。
打造活跃、健康的开源社区: Kubernetes 是当前最活跃的开源社区,在 github 上已有 1 万 4 千多颗星(相比于其他容器集群项目的数千颗星)。谷歌做开源社区也有重要意义:虽然在市场端不同的厂商可以通过花样繁多的市场手法和资金投入包装自己的产品领先度,开源社区的健壮程度却是无法用钱或市场广告买来的。谷歌通过打造开源社区可以更客观地展现自己在基础设施、容器、集群管理方面的技术优势。当然或许有误区认为项目不活跃是因为软件“成熟”,项目活跃是因为项目不成熟。然而谷歌内部的代码库每天仍有近万个新的 issues 被开启,绝不是因为谷歌 10 多年的业务系统不成熟,而更多的是创新性的一种表现(大部分 issues 是在不断迭代更强大的新功能——在保证稳定的基础上)。由于当今互联网业务千变万化,创新层出不穷,任何系统都需要不断的迭代,如果一个项目因达到“成熟”而活跃度下降,这只是该项目遭到冷落的表现。
现在的空白和未来的趋势
无论是 Docker 还是开源第三方集群管理工具,如要到达 Gifee 都还有很长的路要走。这里我仅仅抛砖引玉列举一些空白和我们希望和正在努力的方向。
发布管理远大于 CI/CD
如今谈到发布,大家想到的就是持续集成( CI )和持续发布( CD )。然而我们在谷歌内部实践的发布管理系统还包括很多其他的方方面面,例如:
如何将镜像的构建与代码库的分支构建相整合; 如何做微服务架构中的联合发布(最重要的是保证新老版本的 API 能够平滑兼容); 如何做版本管理(哪个镜像版本运行在哪个数据中心上); 如何做灰度发布(根据不同的时间节点、步调来有策略的调整新版本的上线比率,自动比对新旧版本的用户行为等)
Devops 远大于 Docker
Devops 包含方方面面,其中诸多实践都是 Docker 自身层面所不能企及的,以谷歌为例:
○配置管理:要做到真正的大环境一致,必须将配置完全与代码分离,这里的配置远不仅仅是服务之间的 IP 地址(通过 DNS 服务发现可以解决),还包括不同环境下对于不同服务、应用的配置参数等。对于这些状态、配置、数据、文件的维护则需要额外的配置管理系统。
○分布式测试:测试是 Devops 中不可或缺的一环,但是在大规模应用系统中,如何有效地、智能地快速自动运行系统测试则需要额外的系统;在谷歌内部我们构建了分布式测试系统,能够基于 Borg ,有选择地识别出收到某个 commit 影响的测试集进行高效自动化测试。
○智能预警: Docker 或容器只是应用运行的载体,而 Docker 自身失效后需要第三方系统来检测并预警。谷歌打造了复杂、灵活的预警系统,可以支持自定义的预警规则和报警行为。
○智能故障定位:微服务架构的分布式天性将系统问题调试变得更加复杂,一个用户的请求在系统内部要遍历多个服务模块,而在出现问题时如何帮助系统管理员自动定位故障也需要额外的工具和系统来完成。
集群管理远大于服务管理
最后想澄清的一个名词是”集群管理“。现在当人们谈及“集群管理”时,容易直接和 Kubernetes , Mesos 等划等号。然而集群管理在谷歌内部是一个非常庞大的组织, Borg 只能算作任务管理或应用管理,除此之外一个真正的集群管理系统还需要涉及到机器管理、网络管理、安全管理等诸多方面:
○机器管理:如何自动配置、安装机器,如何自动进行机器层面的问题检查与修复
○网络管理:如何与 SDN 联动
○安全管理:如何在容器的基础上做应用、业务层面的安全检测
作者介绍:
才云 联合创始人 & CEO 张鑫:
曾为美国谷歌软件工程师,从事谷歌核心技术底层系统研发。 2012 年至 2014 年,作为主要技术人员从事谷歌数据中心( IDC )集群管理系统( Cluster Management )的研发,该集群系统自动管理和维护 95%以上的谷歌集群机器;带头开发的自动故障应对系统将谷歌集群的故障率大大降低,为谷歌节省了每年千万美元的运维成本;作为核心技术人员参与了谷歌云计算平台的系统到产品的全栈式开发;开发的图形化应用部署( Click-to-deploy )、部署经理( Deployment Manager )等产品上线后即获得用户广泛使用;设计了谷歌倡导的新一代“云服务”( Managed Cloud )的设计,此理念获得了美国 IBM , VMWare , Redhat 等云计算巨头公司一致响应。
于 2012 获美国顶级计算机学府 Carnegie Mellon University (CMU)大学计算机博士学位,发表国际学术论文数十篇,成为分布式系统和网络安全方向的学术专家,曾为美国个性医疗初创公司 SMART-MD, AllPancreas 提供应用软件平台构架、安全技术咨询和基于云平台的系统开发