您的位置:首页 > 运维架构 > Kubernetes

[细说] 什么原因让Kubernetes放弃Libnetwork技术?

2018-10-19 00:08 197 查看



自1.0版发布以来,Kubernetes已经拥有了一种非常基本的网络插件形式,大约与Docker的Libnetwork和容器网络模型(CNM)一起推出。与Libnetwork不同,Kubernetes插件系统仍保留其“alpha”标识。


现在Docker的网络插件支持已经发布并得到支持,我们得到的一个明显问题就是为什么Kubernetes还没有采用它。毕竟,供应商几乎肯定会为Docker编写插件 我们都会更好地使用相同的驱动程序,对吧?

在进一步讨论之前,重要的是要记住Kubernetes是一个支持多个容器运行时的系统,Docker只是其中一个。配置网络只是每个运行时的一个方面,所以当人们问“Kubernetes是否支持CNM?”时,他们的真正意思是“kubernetes是否支持使用Docker运行时的CNM驱动程序?”如果我们能够跨运行时实现通用网络支持,那再好不了,但这不是一个明确的目标。


的确,Kubernetes并没有在Docker运行时采用CNM/Libnetwork。事实上,我们一直在研究由CoreOS提出的替代容器网络接口(CNI)模型和App Container规范的一部分。为什么?有许多原因,无论是技术还是非技术。


首先,Docker网络驱动程序的设计中有一些基本假设会给我们带来麻烦。Docker有一个“本地”和“全局”驱动程序的概念。本地驱动程序(如“桥”)是以单节点为中心的,不会执行任何跨节点协调。全局驱动程序(例如“Overlay”)依靠Libkv(一个键值存储抽象)来跨节点进行协调。这个键值存储是另一个插件接口,并且是非常低级的(键和值,没有语义含义)。


要在Kubernetes集群中运行诸如Docker overlay驱动程序之类的东西,我们需要集群管理员运行一个完全不同的Consul实例,etcd或Zookeeper(请参阅多主机网络),否则我们将不得不提供我们自己的被Kubernetes支持的Libkv实现。


后者听起来很有吸引力,我们试图实现它,但是libkv接口是非常低级的,并且schema是在Docker内部定义的。我们不得不直接暴露底层的键值存储,或者提供键值语义(在我们的结构化API之上,它本身是在键值系统上实现的)。由于性能,可扩展性和安全性原因,这两者都不具有吸引力。最终结果是,整个系统将显得更加复杂,但是使用Docker网络的目标应该是件简化事情。


对于愿意并能够运行必要的基础设施以满足Docker全局驱动程序并自行配置Docker的用户,Docker网络应该“只是工作”。Kubernetes不会妨碍这样的设置,无论项目的方向如何,该选项都应该可用。然而,对于默认安装,实际结论是,这对用户来说是一种不必要的负担,因此我们无法使用Docker的全局驱动程序(包括“Overlay”),这消除了使用Docker插件的许多价值。


Docker的网络模型提出了许多对Kubernetes无效的假设。在Docker版本1.8和1.9中,它包含一个从根本上有缺陷的“发现”实现,导致容器中的/etc/hosts文件损坏(docker#17190), 并且这不容易关闭。在版本1.10中,Docker计划捆绑一个新的DNS服务器,目前还不清楚这是否可以关闭。


容器级命名不是Kubernetes的正确抽象 -我们已经有了我们自己的服务命名,发现和绑定的规则,并且我们已经有了我们自己的DNS模式和服务器(基于完善的SkyDNS)。捆绑的解决方案不足以满足我们的需求,但也不是无法使用的。由于本地/全局的划分,Docker具有进程内和进程外(“远程”)插件。我们调查了是否可以绕过libnetwork(从而跳过上述问题)并直接驱动Docker远程插件。不幸的是,这意味着我们不能使用任何Docker进程内插件,特别“bridge”和“overlay”,这再次消除了libnetwork的很多实用性。


另一方面,CNI在哲学上与Kubernetes更加一致。它比CNM简单得多,不需要守护进程,并且至少可以跨平台(CoreOS的rkt容器运行时支持它)。跨平台意味着有机会启用网络配置,这些配置将在运行时间内保持一致(例如Docker,Rocket,Hyper)。


它遵循UNIX做好一件事的哲学。 此外,包装CNI插件并生成更加定制的CNI插件也很简单 - 可以使用简单的shell脚本完成。 CNM在这方面要复杂得多。这使CNI成为快速开发和迭代的有吸引力的选择。早期的原型已经证明,可以将kubelet中几乎100%的当前硬编码网络逻辑弹出到插件中。


我们分析了为Docker写一个Bridge的CNM驱动,运行CNI驱动,事实证明这非常复杂。


首先,CNM和CNI模型非常不同,所以没有一个“方法”排队。我们仍然有上面讨论的全局与本地和键值问题。假设这个驱动程序会声明自己是本地的,我们必须从Kubernetes获得有关逻辑网络的信息。不幸的是,Docker驱动程序很难映射到像Kubernetes这样的其他控制平面。具体而言,驱动程序不会被告知容器所连接的网络的名称 只是Docker在内部分配的ID。这使得驱动程序难以映射回到另一个系统中存在的任何网络概念。


这个问题和其他问题已经由网络供应商提供给Docker开发人员,并且通常以“按预期工作”(lbnetwork#139,libnetwork#486,libnetwork#514,libnetwork#865,docker#18864)关闭,尽管它们使非Docker第三方系统更难以集成。


在整个调查过程中,Docker已经明确表示,他们对于偏离当前过程或委托控制的想法并不是很开放。这对我们来说是非常令人担忧的,因为Kubernetes补充了Docker并增加了很多功能,但存在于Docker本身之外。由于所有这些原因,我们选择投资CNI作为Kubernetes插件模型。这会有一些不幸的副作用。他们中的大多数都相对较小(例如,Docker检查不会显示IP地址),但有些是重要的。


特别是,由Docker运行启动的容器可能无法与Kubernetes启动的容器进行通信,如果网络集成商想要与Kubernetes完全集成,则必须提供CNI驱动程序。另一方面,Kubernetes将变得更简单和更灵活,并且早期引导的许多丑陋(例如配置Docker使用我们的桥)将会消失。


随着我们沿着这条道路前进,我们一定会保持眼睛和耳朵的畅通,以便更好地整合和简化。如果您对我们如何做到这一点有想法,我们真的很想听到他们,可以通过slack.k8s.io和邮件列表找到我们。

链接:https://kubernetes.io/blog/2016/01/why-kubernetes-doesnt-use-libnetwork/


关于Kubernetes技术内容和总结,请点击阅读原文参考<Kubernetes技术和实战总结>电子书,获取更多技术内容,具体内容如下所示。



推荐阅读:



温馨提示:
请搜索“ICT_Architect”或“扫一扫”二维码关注公众号,点击原文链接获取更多电子书详情。 [strong]求知若渴, 虚心若愚[/strong]

阅读更多
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: