編者按:這是根據Kubernetes 1.3新功能寫的一系列的深入文章,本文是第二篇。
我們很高興地宣布:作為Kubernetes 1.3的一部分,把通用容器引擎加入Kubernetes的工作有了初步成果。我們親切地稱之為“rktnetes”,目前rktnetes包含在Kubernetes?1.3代碼庫中,并已經可以用于開發用途。rktnetes集成了對CoreOS rkt容器引擎的支持,目前已經成為Kubernetes的主線代碼的一部分。對于開發和運維人員,在Kubernetes中使用不同的容器引擎比以往任何時候都更為簡單。
PayPal Xoom服務高級MTS兼架構師Mark Petrovic說:“rkt與底層systemd的集成方式很給力,我們認為rkt在kubernetes生態中是一個非常優秀的容器引擎。rkt運行時只提供必要的功能,然后將其他交給另外合適的系統服務來處理。這種分離對我們來說很重要”
rktnetes是一套代碼庫,它允許Kubernetes節點使用rkt而非Docker來運行容器。這個項目為Kubernetes增加了新的功能,例如在更加靈活的隔離級別下運行容器。 rkt 提供了另一種容器引擎架構,反映了隔離、模塊化的UNIX哲學。為支持rktnetes而做的工作也為Kubernetes開辟了新的可能性,如支持多種容器鏡像的格式、集成為特定應用場景(或平臺)打造的容器引擎。
為什么Kubernetes需要rktnetes?
rktnetes不僅僅是rkt,它也是對Kubernetes接口的提煉,為今后其他模塊化的容器運行時鋪平了道路。盡管Docker被人熟知并且目前是Kubernetes默認的容器引擎,但某些集群可能需要特定的容器引擎,所以將容器引擎插件化可以帶來很多好處。要以rkt做為開端保持各組件接口間的簡潔,來確保Kubernetes的設計具有足夠的靈活性來支持多種容器引擎。
目前Kubernetes使用的容器引擎(暗指docker?engine)強加了一些設計決策。在這樣一個快速發展的項目里,嘗試其他容器引擎是值得的。當Kubernetes給節點發送請求來啟動pod時,它通過每個節點上的kubelet與默認容器引擎主進程通信(暗指docker?daemon),容器引擎主進程負責管理該節點上所有的容器。
rkt daemon沒有采用一體化架構。值得注意的是,默認的容器引擎(Docker)正在重構原來的一體化架構。rkt在設計之初就將模塊化原則運用到極致,包括重用經過充分測試的已有系統組件,而不是重新實現它們。
rkt把構建容器鏡像的任務從容器引擎抽離出來,以一個獨立的功能存在。容器的生命周期管理也以同樣的方式實現。二進制文件rkt負責配置運行時環境和準備鏡像,然后啟動容器和容器運行環境。從這一點來看,rkt程序只做了“一件事”然后由isolator接管。
Kubernetes使用查詢容器引擎和Pod狀態的API來跟蹤集群每個節點的工作,這些API作為一個單獨的服務,將協調和編排功能與容器引擎核心隔離開。雖然該 API服務沒有實現當前默認容器引擎(docker?engine)的所有API功能,但它已經能夠將容器與容器引擎的失敗和升級隔離開,并為查詢容器元數據提供了期望API的只讀部分。
通過使用rkt 管理容器的執行,Kubernetes可以利用CoreOS容器引擎的stage1隔離機制的優勢。典型的 rkt 容器提供軟件級的隔離環境,它通過Linux內核命名空間,cgroups和其他組件來構成。以這種方式進行隔離的容器會與系統上的所有其他容器共享同一內核,將運行的應用進行輕量級的隔離。
然而rkt 提供了插件化的隔離環境,稱為stage1,用來改變容器的執行和隔離方式。例如,rkt fly stage1在主機命名空間(PID、mount、網絡等)運行容器,給予容器在主機系統上更大的權限。類似kubelet,fly 用于容器化底層系統和網絡軟件。與之相反,KVM stage1以獨立的虛擬機來運行標準的應用容器,每個虛擬機都有自己的Linux內核,通過KVM hypervisor進行管理。這種隔離級別可以用于高安全性和多租戶的集群環境。
目前rktnetes可以通過設置kubelet的 --rkt -stage1-image 選項,以KVM stage1執行節點上的所有容器。通過在Kubernetes的annotation中聲明Pod的stage1來選擇隔離級別。KVM容器和標準的Linux容器可以混合在同一個集群中。
rkt如何與Kubernetes一同工作
目前Kubernetes通過Docker daemon提供的API來控制默認的容器引擎。rktnetes與 rkt的通信則有些不同。首先,kubernetes涉及到修改容器狀態的操作和只讀操作是完全分離的,通過兩個不同的組件實現。涉及到修改容器狀態的操作有:如何啟動/停止pod、擴容/縮容失敗時重新調度pod、只讀操作有編排器查詢pod元數據用于定期記錄。
每個集群節點上的kubelet使用rkt來準備容器及pod內的環境,使用 systemd來調度和管理 pod 進程。Pod作為systemd的服務被管理,然后 kubelet 通過 dbus 發送systemd命令來控制它們。涉及生命周期管理的操作,均是kubelet通過systemd來實現,這些操作包括重啟失敗的pod、殺掉結束的進程等。
分散的?rkt API服務實現了Kubernetes需要的pod內省機制。每個節點上的kubelet 使用systemd啟動、停止和重啟?pod?時,它還可以通過API服務讀取容器運行時的元數據。這些元數據包括基本的編排信息,如在節點上運行的?pod? 數量、pod的名字和網絡設置、pod 配置細節、資源限制以及存儲卷(想一下kubectl describe命令顯示的信息)。
寫入journal文件的pod日志,能夠被kubelet logs和其API服務的其它子命令所用。API服務從文件中讀取pod日志發送給kubelet以響應kubernetes控制平面的請求。
容器環境的雙接口正處于活躍的開發中,我們也在計劃為API擴展一些操作pod的命令。底層機制將繼續保持“separation of concerns”原則,面向kubelet會更加透明。隨著時間的推移,kubelet控制rktnetes容器引擎與控制默認容器引擎接口的區別將會越來越小。
嘗試rktnetes
你能用 rktnetes做什么?目前rktnetes通過了所有適用Kubernetes的“end-to-end”(又名“e2e”)測試,為cAdvisor 提供了標準的度量,使用CNI 管理網絡,處理每個容器/pod日志并自動對舊容器和鏡像進行垃圾回收。運行在 rkt上的Kubernetes為集群提供的不只是基本的模塊化,還有更加靈活的容器運行時,更是我們在CoreOS開發環境的一部分。
開發者和早期使用者可以根據 rktnetes note中的已知問題獲得有用的想法。這個列表列出了需要引入rktnetes的高優先級需求。我們也希望你在 Kubernetes 集群中嘗試rktnetes。
在Kubernetes中使用rkt(http://kubernetes.io/docs/getting-started-guides/rkt/)的入門指南開啟使用rktnetes集群的第一步,介紹了從kubelet --container-runtime=rkt 到網絡配置和啟動pod的功能。這篇指南也介紹了在GCE上使用Kubernetes kube-up.sh 腳本啟動集群的配置。
目前的工作是使rktnetes集群化。雖然還沒有進行合并,但一個進行中的pull request添加了單獨的rktnetes配置項,當使用coreos-kubernetes工具來部署Kubernetes集群時可使用此配置項來選擇rkt做為容器引擎。你還可以檢出rktnetes?workshop項目,這個項目用vagrant命令在任一機器上啟動一個單節點rktnetes集群。
我們期待更多的Kubernetes和CoreOS社區為rktnetes做出貢獻,我們非常歡迎你加入我們并提交request!
原文鏈接:http://blog.kubernetes.io/2016/07/rktnetes-brings-rkt-container-engine-to-Kubernetes.html
您也可以關注我們的官方微信公眾號(ID:ctoutiao),給您更多好看的內容。