为什么docker还不能广泛用于生产中

Posted windmissing

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了为什么docker还不能广泛用于生产中相关的知识,希望对你有一定的参考价值。

这段时间,docker的发展更好了,但是也明显碰到了一些棘手的问题。然而,对于今天的许多产品用户来说,支持者并不比反对者多。docker使得开发、测试、CI(持续集成)环境对开发者们不可见,在一点上,docker确实做得非常好。然而,它已经干扰了生产。基于docker大会2015年的主题“生产中的docker”,我想要公开地讨论一下docker广泛采用的生产用例将要面对的挑战。这些话题都不是新的,都以某种形式在github中出现过了。其中大多数,我已经在“会议讨论”上或者与docker团队讨论过了。这篇文章显然不是为了指出哪一个不再是话题:例如新的registry修复了以前的许多不足。许多地方仍然存在问题,但这里没有提及。但我相信,下面的内容非常重要,可以短期内让更多的组织带头将容器用于生产中。这个列表主要来自于我自身使用docker的经验。我把内核平台放到容器中运行了一年多。通过一项和Docker移动一样快的技术,可以保证所有东西都是实时的。如果发现我的表述不准确,请指出来。
创建镜像文件 为大型应用创建容器镜像文件仍然是一个挑战。如果我们打算依靠容器镜像文件来做测试、CI和紧急部署,我们需要在一分钟内准备好镜像文件。dockerfile使得这一点几乎不可能。为了方便使用,就会处于一个抽象层比较高的位置,以致于不能处理这些复杂的用例: 不同频道信息传输为特别重的应用或者特定应用的依赖做高速缓存 在创建镜像文件时,没有允许就进入了镜像文件的私密处 在最终的镜像文件上控制所有的镜像文件层 创建镜像层时的平行处理
大多数人不需要使用这些特性,但是对于大型应用,要想做到快速创建,这些是必须的。配置管理工具,如Chef、Puppet,使用广泛,但是对于创建镜像文件来说,太重量级了。我打赌这种系统将会在接下来的十年中淘汰。然而,许多应用需要依靠它们提供支持、部署和协调。dockerfile现在还不能真正地抓住配置管理的复杂性,但这个复杂性需要被管理。在shopify,我们不再通过docker提供的接口创建我们自己的系统。这是很痛苦的。我希望这种痛苦不会发生在别人身上。我想要抛弃这种痛苦,但我必须表露我自己。很少有人会对生产中的容器争论这么久。
将会出现的是不整洁,现在不是一个做了更多的探索的领域(一个例子是dockeramp,另一种包)。docker引擎将来会把基本体(增加文件、设置入口点等)从客户端分离。版本合并1.8已经让这些更容易了,通过配置管理供应商、爱好者和公司,让这些领域开放。基于提供系统的历史,很想相信用一个标准就可以解决问题,我们更倾向于在运行时解决。创建可计量的镜像文件的观点是很不清晰的。基于我的认识,没有人会积极地迭代,但很不幸,这种方法已经使用了超过一年。
垃圾回收 每个主要的docker部署的最后一步通常都是写一个垃圾收集器从主机移除旧的镜像文件而告终。这里可以有许多种启发式算法,例如删除X天以前的镜像文件,并且至多主机上有y个镜像文件。Spotify最近把它们的方法开源了。我们以前很长一段时间也自己写。我能理解为垃圾回收设计一个UI是多么困难的事,但它确实需要。大多数人在他们产品的box空间爆满时候才偶然发现他们有这方面的需求。最终,你会运行到同一个镜像文件,因为registry里面充满了很大的镜像文件。这个问题在分布的路线图上。
迭代的速度和core的状态 在1.5以前的版本里,Docker非常关注稳定性,却在运行产品时入口的界限方面做的工作比较少。为容器开发一个公共的心智模型会让docker更加成功。他们也担心会毁掉它。每个UX更新经过过多的流程时迭代速度会受到影响。至于1.7,docker以试验性的版本为特色,以网络和存储插件为主。这些特性被显式地打上了“测试版”的标签,可能随时会被从内核或者主要更新中除去。对于已经打算用docker的公司来说是件好事:因为它上内核组在开发新特性上有更快的迭代,而不用关心由于失败回退导致的小版本之间的不兼容。对于公司来说,修改docker核心仍然是困难的,因为这需要一个fork(一个灾难性的下滑和维护的负担),或获取。。。的认可。至于1.7,拥有插件的声明,这一问题的策略很明显:把每一种方案做成一个插件。在七月分的docker会议中,很高兴得知这个有关节的在插件的保护下作为一个高优先级的团队(对我个人来说很有意义,因为插件是我最喜欢的操作)。尽管未来看起来很有前途,这仍然是个痛点,在过去两年一直是。
日志 有一个领域可以从早期的变化中获利,那就是日志。很难有一个问题,但是不是唯一的问题。现在没有很好很通用的解决方案。一般它们都使用地图:尾日志文件,容器内日志,主机日志,主机系统日志的日志,通过fluentd,直接从网络记录应用的日志,或者记入日志到一个文件然后用另一个进程把日志发给kafka。在1.6版本中,对日志驱动的支持被合到了核心版本。然后核心必须接受驱动(通常很不容易)。在1.7版本中,试验性地支持不同进程的插件被合进来了,但是(很遗憾),它并没有合入日志驱动。我相信1.8在计划这个,但官方记录里没有说。就这一点,卖主们会写它们自己的日志驱动。把日志驱动分享到社区只是一件小事,大型的应用不再需要求助工程学来处理一个通常的解决方案。
私密 在与captivating同一个目录下,我们找到私密。大多数使用容器的人都依赖于对私密的安全的配置管理。然而,持续的深入私密配置管理的路径。另一个替代方案的是把它们与镜像文件区分,但是这会导导致安全风险,使安全镜像文件的循环在开发、CI和产品中产生困难。直到最近,还不存在容器为导向的东西,但最近两个平行的私密破坏-Vault和Keywhiz,都是开源的。在shopify,我们开发了ejson一年半,解决了这个问题,管理非对称的私密脚本文件用JSON。然而,它基于运行在理想化的环境的假设。
文件系统 docker基于文件系统(联合文件系统上的LWN系列支持CoW)的CoW(写时复制)。这使得如果有100个容器来自于同一个镜像文件,你不需要100倍的磁盘空间。相反,每一个容器在镜像文件上创建一个写时复制层,只有当原镜像文件中有文件被改变时在真正地分配空间。好的空间用户对容器内的文件系统的影响很小,像这样的改变意味着容器的状态是no-no。这种状态存储在volume中,指示主机或者网络。另外,层节省了空间,因为部署的镜像文件通常是相似的,或者有相同的层。文件系统在linux上支持CoW的问题是它们比较新。在shopity,有一些棘手的体验: AUFS。看上去完整,我们不得不增加。市况萧条,花了很多钱。基于代码很大,难以阅读,很可能就是不能被主流接受需要一个核心客户的原因。 BTRFS。有一个学习曲线,通过一系列新的工具例如du和ls不起作用。相对于AUFS,我们对于内核锁,而不需要为了更新与内核版本玩猫和老鼠的游戏。接近磁盘空间容量时,BTRFS的行为不可预测。这样的1000个CoW层时,行为同样不可预测(BTRFS技术中的子卷)。BTRFS要用很多钱。 OverlayFS。这个已经被合到linux内核3.18中了,而且非常稳定,效率也很高。由于它能够在i节点间共享页缓存,所以花费要少得多。不幸的是,它要求你必须使用比较新的内核,而且大部分版本中不能使用,所以你通常需要自己去构建一个。 docker很幸运,overlay很快就会变得通用了,但是,根据我们的经验,AUFS的默认版本对于有大量结点的产品来说,仍然很不安全。很难说这里会做什么,尽管大多数版本不会移植内核(这也是被推荐或者拒绝的原因),尽管很明显有空间。看来我们不得不等待。
对内核特性的依赖 正如docker依赖文件系统,它也会影响内核的附加物,也就是命名空间和(不是最近,但是也不是很常用)cgroups。这些特性(尤其是命名空间)还不能被工厂广泛接受。曾经有一次因为这些进入难以理解的bug中。我们在运行产品时禁用网络命名空间,因为我们遇到了许多用于实现的软件锁,但是还没有资源去修复主流。内存cgroup使用大量的内容空间,我从未证实的小道消息听说。

以上是关于为什么docker还不能广泛用于生产中的主要内容,如果未能解决你的问题,请参考以下文章

ROC曲线原理实例分析 【1】

Docker 编译 缓存?

用于PostgresQL的本机Azure数据库与Azure VM中的PostgresQL docker容器

使用 OpenResty Docker 镜像快速搭建 Web 服务器

Docker的“正反”面

Java 这一年:IntelliJ 称霸 IDE,Kotlin 成最大赢家!