天天看點

為什麼Kubernetes不使用Libnetwork?

本文講的是<b>為什麼Kubernetes不使用Libnetwork?</b>,【編者的話】Libnetwork是2015年5月1日Docker釋出的容器網絡管理項目。Libnetwork使用Go語言編寫,目标是定義一個容器網絡模型(CNM),并為應用程式提供一緻的程式設計接口以及網絡抽象。為什麼後來釋出的Kubernetes在網絡管理方面,沒有使用Docker中的Libnetwork呢?且聽Google工程師怎麼說。

深入讨論之前,首先我們要知道:Kubernetes是一個支援多容器的運作環境,而Docker隻是其中一個容器而已。每一個運作環境都會去配置網絡環境,是以當人們問“Kubernetes将會支援CNM嗎?”時,他們真正的意思是“Kubernetes是否在Docker運作時下支援CNM?”。我們當然希望利用同樣一個網絡插件來支援所有的運作環境,但是這并不是一個絕對的目标。

首先,在Docker的網絡驅動設計中,預先做了一些相容的基本假設,這給我們帶來不少的問題。

聽起來後者更有吸引力一些,而且我們也正在嘗試實作它。但是,libkv的接口太過于底層,而且它的架構模式也是Docker内部的量身定制版,我們要麼直接暴露底層的key-value存儲,要麼提供key-value語義接口(在一個key-value系統上實作結構存儲的API)。就起性能、可擴充性和安全性而言,以上兩種方案都不是太合适。我們使用Docker網絡的目标是簡化操作,如果那樣做的話,很明顯會使整個系統将變得更加複雜。

對于那些想運作 Docker 的全局驅動并有能力配置 Docker 的使用者來說,Docker 的網絡應該是“可行的”。對 Kubernetes 來說,我們不希望介入或影響 Docker 的配置步驟,并且不論 Kubernetes 這個項目今後如何發展,這一點應該都不會改變。Docker 的全局驅動是對使用者和開發者來說增加了多餘的負擔,并且我們不會用它作為預設的網絡選項,這也意味着使用 Docker 插件再沒什麼價值。

除了“本地/全局”驅動這樣的區分,Docker 還定義了“程序内”和“程序外”(“遠端”)插件。我們還研究了下是否可以繞過 libnework 本身(這樣就能避開之前所述的那些問題)來直接使用”遠端“插件。不幸的是,這意味着我們同時也失去了使用 Docker 的那些“程序内”插件的可能,特别是”bridge”和”overlay”這樣的全局插件。這又令使用 libnetwork 失去了很大一部分意義。

另外,包裝 CNI 子產品來實作一個自定義的子產品是非常簡單的-通過一個簡單的 shell 腳本就可以完成。相反 CNM 就複雜多了。是以我們認為 CNI 更适合快速開發和疊代。早期的實驗嘗試證明我們可以利用 CNI 插件來替代幾乎所有 kubelet 中寫死的網絡邏輯。

我們也嘗試為 Docker 實作了一個 “bridge”CNM 驅動來使用 CNI 的驅動。結果表明這更加複雜了問題。首先 CNM 和 CNI 的模型非常不同,沒有一個“methods”能把它們很好的相容。其次,我們還是有之前提到的“全局”和“本地”以及 key-value 的問題存在。假設這是個本地驅動,那麼我們仍舊要從 Kubernetes 中去得到相應的邏輯網絡的資訊。

不幸的是,Docker驅動很難映射接入到類似Kubernetes這樣的管理平台。特别是這些驅動使用了 Docker 内部配置設定的一個 ID 而不是一個通用的網絡名字來指向一個容器所屬的網絡。這樣的設計導緻一個被定義在外部系統中(例如 Kubernetes )的網絡很難被驅動所了解識别。

種種原因緻使我們選擇了 CNI 作為 Kubernetes 的網絡模型。這将會帶來一些令人遺憾的副作用,雖然絕大部分都是一些小問題,比如 Docker 的 inspect 指令顯示不了網絡位址。不過也會有一些顯著的問題,特别是被 Docker 所啟動的容器可能不能和被 Kubernetes 啟動的容器溝通,以及網絡整合工程師必須提供 CNI 驅動來把網絡完全整合到 Kubernetes 中。但重要的是,Kubernetes 會變得更簡單、靈活并且不需要進行提前配置(比如配置 Docker 使用我們的網橋)。

原文釋出時間為: 2016-01-21

本文作者:ylzhang 

本文來自雲栖社群合作夥伴DockerOne,了解相關資訊可以關注DockerOne。

原文标題:為什麼Kubernetes不使用Libnetwork?