为什么Kubernetes不使用libnetwork

Kubernetes 在 1.0 版本之前就已经有了最初的网络插件。与此同时 Docker 也引入了 libnetwork 和 Container Network Model (CNM)。现在 Docker 已经发布并支持了网络插件 libnetwork,然而 Kubernetes 的插件却还停留在 alpha 阶段。 那么一个显而易见的问题是为什么 Kubernetes 还没有采用 libnetwork。毕竟大部分的供应商都肯定会支持 Docker 的插件,Kubernetes 也理所应当采用它。

在开始讨论之前,我们首先需要知道的一点是: Kubernetes 是一个支持多种容器运行环境的系统,Docker 只是其中之一。配置网络对于每个运行环境都是同样重要的。所以当人们问到“ Kubernetes 支持不支持 CNM 时”,他们其实是在问“Kubernetes 会不会在 Docker 运行环境下支持 CNM”。我们当然希望利用同样一个网络插件来支持所有的运行环境,但是这并不是一个绝对的目标。

然而,Kubernetes 并没有在其 Docker 运行环境中采用 CNM/libnetwork。最近一段时间,我们一直在研究探讨能否使用 CoreOS 推出的 App Container (appc) 中的网络模型Container Network Interface (CNI) 去替代它。为什么?这里面有各种技术上和非技术上的原因。

首先,Docker 的网络驱动设计做了一些兼容性不佳的基本假设,这给我们带来了不少困难。

比如 Docker 里面有本地和全局驱动的概念。本地驱动(比如 “bridge”)固定于一台机器而不能做跨机器的远程协调。全局驱动(比如 “overlay”)依赖于 libkv 库去做跨机器间的协调。该库定义了一个 key-value 存储的接口,并且接口非常的底层。为了让 Docker 的全局驱动在 Kubernetes 集群上跑起来,我们还得需要系统管理员去运行 etcd, ZooKeeper, Consul 的实例(具体看 Docker 的 multi-host network 文档); 或者我们得在 Kubernetes 里面提供另一套 libkv 的实现。

不过相比之下,第二种方案(全局驱动)看起来更灵活,更好,所以我们尝试去实现它。但是 libkv 的接口非常底层,它的模式也是为了 Docker 运行环境自身设计的。对于 Kubernetes 来说,我们要么直接暴露出我们的底层 key-value 接口,要么提供一个 key-value 的语义接口(也就是在一个key-value系统上实现结构存储的API)。就性能、伸缩性和安全角度而言,这两个选择对我们来说并不是非常合适。如果我们这样实现的话,整个系统会变明显地变得复杂。这和我们希望利用Docker的网络模型来简化实现所冲突。

对于想要运行 Docker 的全局驱动并能有能力配置 Docker 的用户来说,Docker 的网络应该会运行得很好。对 Kubernetes 来说,我们不希望介入或影响 Docker 的配置步骤;并且不论 Kubernetes 这个项目今后如何发展,这一点应该不会改变。甚至,我们会努力兼容更多的选项给用户。但我们在实践过程中得到的结论是:Docker 的全局驱动是对用户和开发者来说增加了多余的负担,并且我们不会用它作为默认的网络选项——这也意味着使用 Docker 插件的价值很大程度上被排除在外。

与此同时,Docker 的网络模型在设计上还做了很多和 Kubernetes 不兼容的假设。比如说在 Docker 1.8 和 1.9 的版本中,它在实现“服务发现(Service discovery)”时有一个根本性的设计缺陷,结果导致了容器中的 /etc/hosts 文件被随意改写甚至破坏(docker #17190 ) ——而且我们还不能轻易关闭“服务发现”这个功能。在 1.10 的版本中,Docker 还计划增加捆绑一个新 DNS 服务器 的功能,而我们现在还不不清楚这个功能能否被关闭。对 Kubernetes 来说,把命名寻址绑定在容器层面,并不是一个正确的设计——我们已经自己定义了一套 Service 命名、寻址、绑定的概念和规则,并且我们也有了我们自己的 DNS 架构和服务(构建在非常成熟的 SkyDNS 上)。所以,捆绑一个 DNS 服务器这样的方案并不能满足我们的需求,而且它还有可能无法被关闭。

除开所谓“本地”,“全局”驱动这样的区分,Docker 还定义了“进程内”和“进程外”(“远程”)插件。我们还研究了下是否可以绕过 libnework 本身(这样就能避开之前所述的那些问题)来直接使用”远程“插件。不幸的是,这意味着我们同时也失去了使用 Docker 的那些“进程内”插件的可能,特别是像网桥(bridge)和覆盖网络(overlay)这样的插件。这令使用 libnetwork 这件事本身失去了很大一部分意义。

另一方面,CNI 和 Kubernetes 在设计哲学上就非常一致。它远比 CNM 简单,不需要守护进程,并且至少是跨平台的(CoreOS 的 rkt 容器支持 CNI)。跨平台意味着同一个网络配置可以在多个运行环境下使用(例如 Docker, rkt 和 Hyper)。这也非常符合 Unix 的设计哲学:把一件事情做好。

另外,包装 CNI 模块来实现一个更定制的模块是非常简单的-写一个简单的 shell 脚本就可以完成。相反 CNM 就复杂多了。因此我们认为 CNI 更适合快速开发和迭代。早期的实验尝试证明我们可以利用 CNI 插件来替代几乎所有 kubelet 中硬编码的网络逻辑。

我们也尝试为 Docker 实现了一个网桥(bridge)CNM 驱动来使用 CNI 的驱动。结果表明这更加复杂了问题。首先 CNM 和 CNI 的模型非常不同,没有一个“方法”能把它们很好的兼容起来。其次,我们还是有之前提到的“全局”和“本地”以及 key-value 的问题存在。假设这是个本地驱动,那么我们仍旧要从 Kubernetes 中去得到相应的逻辑网络的信息。

不幸的是,对于像 Kubernetes 这样的管理平台而言,Docker 的驱动非常难以接入。特别是这些驱动使用了 Docker 内部分配的一个 ID 而不是一个通用的网络名字来指向一个容器所属的网络。这样的设计导致一个被定义在外部系统中(例如 Kubernetes )的网络很难被驱动所理解识别。

我们和其它网络提供商将这些问题和其它一些相关问题都汇报给了 Docker 的开发人员。尽管这些问题给非 Docker 的第三方系统带来了很多困扰,它们通常被以“设计就是如此”的理由所关闭(libnetwork #139libnetwork #486libnetwork #514libnetwork #865docker #18864)。通过这些举动,我们观察到 Docker 清楚的表明了他们对于有些建议的态度不够开放,因为这些建议可能会分散其一些主要精力、或者降低其对项目的控制。这一点让我们很着急,因为 Kubernetes 一直支持 Docker,并且为其增加了如此多的功能,但同时 Kubernetes 也是一个独立于 Docker 之外的项目。

种种原因致使我们选择了 CNI 作为 Kubernetes 的网络模型。这将会带来一些令人遗憾的副作用,虽然绝大部分都是一些小问题,比如 Docker 的 inspect 命令显示不了网络地址。不过也会有一些显著的问题,特别是被 Docker 所启动的容器可能不能和被 Kubernetes 启动的容器沟通,以及网络整合工程师必须提供 CNI 驱动来把网络完全整合到 Kubernetes 中。但重要的是,Kubernetes 会变得更简单、灵活并且不需要进行提前配置(比如配置 Docker 使用我们的网桥)。

随着我们越走越远,我们会毋庸置疑地汲取更多更好的整合、简化的方法。如果您对此有啥想法,我们洗耳恭听——可以通过 Slack (http://slack.k8s.io/) 和 network SIG 邮件列表联系我们。

原文链接:Why Kubernetes doesn’t use libnetwork

时间: 2024-09-29 10:34:19

为什么Kubernetes不使用libnetwork的相关文章

盘点Kubernetes网络问题的4种解决方案

由于在企业中部署私有云的场景会更普遍,所以在私有云中运行Kubernetes + Docker集群之前,就需要自己搭建符合Kubernetes要求的网络环境.现在的开源世界里,有很多开源组件可以帮助我们打通Docker容器和容器之间的网络,实现Kubernetes要求的网络模型.当然每种方案都有自己适合的场景,我们要根据自己的实际需要进行选择. 一.Kubernetes + Flannel Kubernetes的网络模型假定了所有Pod都在一个可以直接连通的扁平的网络空间中,这在GCE(Goog

浅析Kubernetes的工作原理

转至 https://www.cnblogs.com/163yun/p/9518901.html 先放一张Kubernetes的架构图: 整体来看,是一个老大,多个干活的这种结构,基本上所有的分布式系统都是这样,但是里面的组件名称就纷繁复杂,下面将一一解析. 1.元数据存储与集群维护 作为一个集群系统,总要有一个统一的地方维护整个集群以及任务的元数据.而且作为集群系统的控制节点,为了高可用性,往往存在多个Master,在多个Master中间,总要有一个Leader. 在Kubernetes里面,

Docker Swarm和Kubernetes在大规模集群中的性能比较

Contents 这篇文章主要针对Docker Swarm和Kubernetes在大规模部署的条件下的3个问题展开讨论.在大规模部署下,它们的性能如何?它们是否可以被批量操作?需要采取何种措施来支持他们的大规模部署和运维? 我们需要使用侧重于用例的基准测试来对所有容器平台进行比较,这样采用者才可以做出正确的决策. 笔者从用户的角度建立了一套测评工具,用普通的方法测试Docker Swarm和Kubernetes.我只评估了通用的功能:容器的启动时间和容器罗列时间. Swarm的性能比Kubern

Kubernetes连接外部数据源

Kubernetes架构下比较核心的问题是数据如何persistance,虽然提供了Persistent volumn的方式,但是对于像数据库之类的产品在kubernetes集群环境中运行和管理还是很有难度的,Kubernetes提供了endpoints这种模式让外部的服务映射成内部的服务,这样比较好的解决了集群对外的连接问题, 如果我们去连接外部的一个oracle数据库,具体的步骤如下: 建立endpoints和service. [[email protected] jdbcservice]#

kubernetes Master部署之Scheduler 以及 HA部署(5)

Kubernetes Scheduler作用是将Controller Manager将要新建的Pod按照特定的调度算法和调度策略绑定到集群中某个合适的Node上,并将绑定信息写入到etcd中. 一.部署Scheduler 下面生成kube-scheduler的kubeconfig文件,操作如下: cd /etc/kubernetes export KUBE_APISERVER="https://192.168.15.200:6443" 配置 cluster kubectl config

Centos7上安装Kubernetes集群部署docker

一.安装前准备 1.操作系统详情 需要三台主机,都最小化安装 centos7.3,并update到最新 cat /etc/redhat-release CentOS Linux release 7.3.1611 (Core)  角色主机名IP Master      master192.168.1.14 node1    slave-1192.168.1.15 node2slave-2192.168.1.16 2.在每台主机上关闭firewalld改用iptables 输入以下命令,关闭fire

基于docker、kubernetes部署openstack到atomic系统上

声明: 本人阅读笔记,翻译类文章仅作意译.如有不对之处,请指出. 需要更本源的理解,请自行阅读英文. 本博客欢迎转发,但请保留原作者信息! 博客地址:http://blog.csdn.net/halcyonbaby 新浪微博:寻觅神迹 内容系本人学习.研究和总结,如有雷同,实属荣幸! 基于docker.kubernetes部署openstack到atomic系统上 openstack的服务定义,是不是看起来很简洁? openstack的实际组件构成,是不是看起来很复杂? 所有的openstack

Kubernetes 集群的两种部署过程(daemon部署和容器化部署)以及glusterfs的应用!

ClusterIp:通过VIP来访问, NodePort: 需要自己搭建负载据衡器 LoadBalancer:仅仅用于特定的云提供商 和 Google Container Engine https://www.nginx.com/blog/load-balancing-kubernetes-services-nginx-plus/ port:相当于服务端口(对及集群内客户访问) targetPort: 相当于pods端口 nodePort: 宿主机端口(也是服务端口,只不过是对集群外客户访问)

在CENTOS7下安装kubernetes填坑教程(原创)

kubernetes(以下简称"k8s")目前是公认的最先进的容器集群管理工具,在1.0版本发布后,k8s的发展速度更加迅猛,并且得到了容器生态圈厂商的全力支持,这包括coreos.rancher等,诸多提供公有云服务的厂商在提供容器服务时也都基于k8s做二次开发来提供基础设施层的支撑,比如华为.可以说k8s也是Docker进军容器集群管理和服务编排领域最为强劲的竞争对手. 现在的Red Hat centos7的用户,已经可以使用熟悉的yum来直接安装k8s,但是真要安装起来,还是有相