容器網絡模型: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 將會成爲將來容器網絡的標準。

相關文章
相關標籤/搜索