歡迎光臨
每天分享高質量文章

[細說] 什麼原因讓Kubernetes放棄Libnetwork技術?

自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”“掃一掃”二維碼關註公眾號,點擊原文鏈接獲取更多電子書詳情

求知若渴, 虛心若愚

赞(0)

分享創造快樂