作者简介:张鑫,杭州才云科技联合创始人 CEO
本文节选自《程序员》,谢绝转载,更多精彩,请订阅《程序员》
责编:魏伟,欢迎投稿和咨询报道,详情联系weiwei@csdn.net

我与容器的缘分起源于我在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的安全性也是经久不衰、流行的议题。

集群工具和Kubernetes的迅猛生产落地

还是要说明上述的论点旨在让企业用户认识到Docker自身不是万灵药,但是我们也不可否认Docker对于软件开发、发布和计算上所带来的变革性优势。如何基于Docker自身的优势更上一层楼,我认为需要顺应“社会专业化分工”,让专业的人做专业的事,通过第三方工具一起打造一个完善的生态系统。

谷歌在十年间打造了三个集群管理系统:Borg、Omega、Kubernetes,原因就是基于它领先于外界多年的容器使用经验,它清楚地意识到容器自身的局限性(只是应用运行的一个“载体”,和其他的载体诸入虚拟机、物理机在这个角度上甚至没有本质区别)。在虽有Mesos这一开源项目的情况下,谷歌还是在2014年决定大力推广Kubernetes项目(内部代号为 “Project 7”),是出于几点深思熟虑。这些出发点也在国外众多知名企业(如eBay等互联网巨头,或高盛、 Bloomberg等金融巨头)和Caicloud在国内一些大型甚至传统国有企业的成功落地中得到了验证):

  1. 谷歌有着更多年的大规模生产级别容器管理经验,这里说的“大规模”是百个数据中心、百万台机器、亿万个容器,且这个“经验”既有成功也有教训。例如通过设计Borg我们清楚地意识到配置管理的重要性,声明性管理的重要性,为每个服务分配独立IP地址来避免端口冲突的重要性等。通过Omega也意识到了可插拔调度器的重要性,模块化系统的重要性,以及对于任务的完成时间的不可控性等。因此Kubernetes希望能够将谷歌内部多年容器管理的理念、经验、教训以开源项目的形式传递给大家,而这个经验是独一无二的。
  2. 另外与Mesos的关注点不同(资源分配),Kubernetes是完全原生态面向服务和集群化容器应用的(Mesos面向的是“框架”),它旨在提供更多便捷的容器管理工具、机制和功能。因此除了常见的任务调度、服务发现、健康检查和自动修复,它还提供了独特的功能,诸如容器组管理,秘密数据管理,服务账户管理,配置管理,守护进程管理,有状态应用管理等,都是谷歌在内部形形色色应用、业务类型管理中所提炼出来的重要功能。
  3. 打造活跃、健康的开源社区:Kubernetes是当前最活跃的开源社区,在github上已有1万4千多颗星(相比于其他容器集群项目的数千颗星)。谷歌做开源社区也有重要意义:虽然在市场端不同的厂商可以通过花样繁多的市场手法和资金投入包装自己的产品领先度,开源社区的健壮程度却是无法用钱或市场广告买来的。谷歌通过打造开源社区可以更客观地展现自己在基础设施、容器、集群管理方面的技术优势。当然或许有误区认为项目不活跃是因为软件“成熟”,项目活跃是因为项目不成熟。然而谷歌内部的代码库每天仍有近万个新的issues被开启,绝不是因为谷歌10多年的业务系统不成熟,而更多的是创新性的一种表现(大部分issues是在不断迭代更强大的新功能——在保证稳定的基础上)。由于当今互联网业务千变万化,创新层出不穷,任何系统都需要不断的迭代,如果一个项目因达到“成熟”而活跃度下降,这只是该项目遭到冷落的表现。

现在的空白和未来的趋势

无论是Docker还是开源第三方集群管理工具,如要到达Gifee都还有很长的路要走。这里我仅仅抛砖引玉列举一些空白和我们希望和正在努力的方向。

发布管理远大于CI/CD

如今谈到发布,大家想到的就是持续集成(CI)和持续发布(CD)。然而我们在谷歌内部实践的发布管理系统还包括很多其他的方方面面,例如:

  1. 如何将镜像的构建与代码库的分支构建相整合
  2. 如何做微服务架构中的联合发布(最重要的是保证新老版本的API能够平滑兼容)
  3. 如何做版本管理(哪个镜像版本运行在哪个数据中心上)
  4. 如何做灰度发布(根据不同的时间节点、步调来有策略的调整新版本的上线比率,自动比对新旧版本的用户行为等)

Devops远大于Docker

Devops包含方方面面,其中诸多实践都是Docker自身层面所不能企及的,以谷歌为例:

  1. 配置管理:要做到真正的大环境一致,必须将配置完全与代码分离,这里的配置远不仅仅是服务之间的IP地址(通过DNS服务发现可以解决),还包括不同环境下对于不同服务、应用的配置参数等。对于这些状态、配置、数据、文件的维护则需要额外的配置管理系统。
  2. 分布式测试:测试是Devops中不可或缺的一环,但是在大规模应用系统中,如何有效地、智能地快速自动运行系统测试则需要额外的系统;在谷歌内部我们构建了分布式测试系统,能够基于Borg,有选择地识别出收到某个commit影响的测试集进行高效自动化测试。
  3. 智能预警:Docker或容器只是应用运行的载体,而Docker自身失效后需要第三方系统来检测并预警。谷歌打造了复杂、灵活的预警系统,可以支持自定义的预警规则和报警行为。
  4. 智能故障定位:微服务架构的分布式天性将系统问题调试变得更加复杂,一个用户的请求在系统内部要遍历多个服务模块,而在出现问题时如何帮助系统管理员自动定位故障也需要额外的工具和系统来完成。

集群管理远大于服务管理

最后想澄清的一个名词是”集群管理“。现在当人们谈及“集群管理”时,容易直接和Kubernetes,Mesos等划等号。然而集群管理在谷歌内部是一个非常庞大的组织,Borg只能算作任务管理或应用管理,除此之外一个真正的集群管理系统还需要诸如机器管理、网络管理、安全管理等诸多方面:

  1. 机器管理:如何自动配置、安装机器,如何自动进行机器层面的问题检查与修复
  2. 网络管理:如何与SDN联动
  3. 安全管理:如何在容器的基础上做应用、业务层面的安全检测

Docker的“谎言”相关推荐

  1. /var/lib/docker/overlay2/xxxxx no such file or directory docker文件删除引发的问题

    记一次误删引发的服务雪崩 K8s node节点磁盘报警,报警后我找到服务中占用磁盘最多的地方,在overlay2目录下,对下面的文件进行了删除   删除后,有状态服务先出现了问题,服务无法启动.停止. ...

  2. 本地打包Docker镜像上传至阿里云远程仓库(一站式脚本)

    打包镜像上传至远程仓库: 1. 本地项目为 mytest-project 2. 仓库为阿里云镜像仓库 registry.cn-beijing.aliyuncs.com/test/mytest-proj ...

  3. docker报错:driver failed programming external connectivity on endpoint, iptables:No chain by that name

    docker 报错: Error response from daemon: Cannot restart container hello: driver failed programming ext ...

  4. Docker容器的备份与恢复,Docker镜像的备份与恢复

    1. 备份容器 首先,为了备份Docker中的容器,我们会想看看我们想要备份的容器列表.要达成该目的,我们需要在我们运行着Docker引擎,并已创建了容器的Linux机器中运行 docker ps 命 ...

  5. docker安装kafka消息队列

    1. 启动zookeeper容器(Zookeeper用于崩溃检测,实现Topic发现,和维护Topic的生产和消费状态) docker run -d --name zookeeper -p 2181: ...

  6. 设置普通用户执行docker命令,执行docker命令无需输入密码或者切换root用户

    每次执行docker命令都要输入密码或者切换root用户,非常不方便,尤其是在shell脚本中就更麻烦了,一起来解决这个问题: 1. 创建名为docker的组,如果之前已经有该组就会提示已存在: su ...

  7. docker :open /var/lib/docker/tmp/GetImageBlob318829910: no such file or directory异常解决

    千万不要直接去重装docker,不要删除镜像,不要手动创建目录和文件,只需要这样就好了!

  8. 将jar包部署在docker上,将jar包打成镜像,使用docker部署jar包

    假设你已经准备好以下东西,即可进行服务部署 一台安装好docker的linux服务器(安装docker见安装docker) 准备好的jar包 接下来开始吧! 将jar包上传至服务器(建好文件夹存放以方 ...

  9. 使用rancher对Docker容器服务升级

    这是笔者以前使用到的一个docker管理工具--rancher 升级服务的步骤 记录一下,说不定有人需要或者以后能用上呢? 1.打包好后上传服务器,编写Dockerfile FROM jdk8apli ...

最新文章

  1. 【考试认证专场】大牛带你全面掌握学习技巧,攻克考试难题(8.2-8.6精品课程限时特惠)...
  2. SaltStack:Salt SSH
  3. 文巾解题1738. 找出第 K 大的异或坐标值
  4. [agc014d] Black and White Tree(玄学树D)
  5. JS 无法清除Cookie的解决方法
  6. Java课程设计---项目数据库设计(含实体类)
  7. python数据结构中文版_Python官方入门教程_中文版_5.数据结构
  8. app用html传数据,通过html调用App并传送参数倒App中
  9. printFinal用法示例
  10. jquery中的attr函数attr(name)、attr(key,value)、attr(properties)、attr(key,fn)、removeAttr
  11. enctype=multipart/form-data的表单无法获取表单中除了type=file以外的其他参数 commons-fileupload 获取除file外其他参数...
  12. web前端课程架构梳理
  13. word文档如何设置四级标题
  14. 单层感知器python_深度学习之单层感知器(一)
  15. mpeg4和mp4格式一样吗?
  16. 解决chm文件打开后跳到某一主页方法
  17. 中国shopify们的来处与归途
  18. 操作系统——PV操作
  19. 【源码】锂电池模型、Simscape语言与Simulink优化设计
  20. IDEA 查找某个 jar 包是如何被引入的

热门文章

  1. linux 防火墙开机启动项,Ubuntu 9.10下实现Firestarter网络防火墙自启动
  2. c 语言如何处理表格文件中的数据库,C#程序从Excel表格中读取数据并进行处理
  3. MyBatis的foreach语句详解
  4. leetcode算法题--最长回文子串
  5. python试卷(有答案版本、个人答案不是官方答案)_python试卷(有答案版本,个人答案不是官方答案).doc...
  6. 窗口最小化之后没有图标
  7. csharp: Aspose.Words create table
  8. 程序猿修仙之路--数据结构之你是否真的懂数组? c#socket TCP同步网络通信 用lambda表达式树替代反射 ASP.NET MVC如何做一个简单的非法登录拦截...
  9. 补天白帽大会:无处不在的无线电攻击
  10. Jquery操作Cookie,保存商品ID值至本地文件中