容器网络模型:CNI vs CNM

docker 的出现是革命性的,改变了咱们开发以及部署项目的方式。社区一直致力于让容器技术标准化,这篇文章主要讨论的是其中的一个方面:网络。docker

网络层面:虚拟机 vs 容器技术

在开始探讨不一样的容器网络标准模型以前,先来从网络角度对比一下虚拟机和 docker。json

虚拟机是一整套操做系统层级的虚拟化,它还会虚拟出虚拟网卡(virtual network interface cards (NIC)),这些虚拟网卡会和真正的物理机网卡相链接。api

docker 实质上就是一个进程,被 container runtime 统一管理,还会共享一个 Linux kernel。因此,容器有更灵活的网络解决方案:网络

  • 和宿主机是共享同一个network interface和 network namespace
  • 链接另外的虚拟网络,使用这个虚拟网络的network interface和 network namespace

容器网络设计

早期的容器网络设计把重点放在了如何链接一个宿主机上的容器,让他们能够和外界进行交互。分布式

在"host"模式中,运行在一个宿主机上的容器使用 host 的network namespace,和宿主机一个ip。为了暴露容器,容器会占用宿主机上的一个端口,经过这个端口和外界通讯。因此,你须要手动维护端口的分配,不要使不一样的容器服务运行在一个端口上。性能

"bridge"模式,在"host"模式的基础上作了些改进。在该模式里面,容器被分配到了一个虚拟的局域网里,在这个network namespace 得到分配到的 ip 地址,因为 ip 地址是独立的,就解决了"host"模式中不一样容器服务不能运行在同一端口的问题。不过仍是有一个问题,若是容器想要和外界通讯的话,仍是须要使用 host 的 ip 地址。这时候须要用到 NAT 将 host-ip:port 转换成 private-ip:port。这一部分的 NAT 规则表示用Linux Iptables 维护的,这会在必定程度上影响性能(虽然不大)。spa

上述的两种模式都没有解决一个问题:多 host 网络解决方案。操作系统

CNI 和 CNM 的对比

  • CNM: Docker 公司(docker container runtime 背后的公司)提出。
  • CNI:CoreOS公司提出。

Kubernetes 在处理网络上,没有选择本身再独立创造一个,而是选择了其中的 CNI做为了本身的网络插件。(至于为何不选择 CNM,能够看看这篇官方的解释:Why Kubernetes doesn’t use libnetwork)。不使用 CNM 最关键的一点,是 k8s 考虑到CNM 在必定程度上和 container runtime 联系相对比较紧密,很差解耦。 有了 k8s 这种巨无霸的选择以后,后来的不少项目都在 CNM 和 CNI 之间选择了 CNI。插件

下面是两种网络模型的详细对比:

  1. CNM

CNM 的 api 包含了两部分:IPAM 插件和网络插件。IPAM 插件负责建立/删除 address pools、分配网络地址,network 插件负责建立/删除 networks、以及分配或收回容器的 ip 地址。事实上,这两种插件均可以实现全部的 API,你能够选择用 IPAM,也能够选择用 network,或者 BOTH。可是,container runtime 会在不一样状况下使用到不一样的插件,这带来了复杂性。还有就是,CNM 须要使用分布式存储系统来保存网络配置信息,例如 etcd。设计

  1. CNI

CNI 对外暴露了从一个网络里面添加和剔除容器的接口。CNI 使用一个 json 配置文件保存网络配置信息。和 CNM 不同,CNI 不须要一个额外的分布式存储引擎。

总结

CNI目前已经得到了众多开源项目的青睐,好比 K8S、Memos、Cloud Foundry。同时被Cloud Native Computing Foundation所承认。CNCF 背后有众多的科技大亨,因此能够预见,CNI 将会成为将来容器网络的标准。

相关文章
相关标签/搜索