支撐大規模公有雲的Kubernetes改進與優化 (1)
Kubernetes是設計用來實施私有容器雲的,然而容器作為公有雲,同樣需要一個管理平臺,在Swarm,Mesos,Kubernetes中,基於Kubernetes已經逐漸成為容器編排的最熱最主流的平臺,網易基於Kubernetes實現了自己的容器公有雲,在這個過程中,需要對Kubernetes進行一定的改進與優化。
架構如下:
網易開發了自己的一個容器服務平臺,將OpenStack的IaaS層和Kubernetes容器層深度融合起來,從而實現一個完整的公有雲體系。從圖中可以看出,容器服務平臺會調度OpenStack的計算服務Nova來創建KVM虛擬機,然後調用Cinder進行雲盤的創建於掛載,調用Neturon進行網絡的創建與連接,然後調用Kubernetes進行容器創建,還可以調用NLB掛載負載均衡器。
一、OpenStack架構很復雜
在容器平臺之前,網易的IaaS層采用的是OpenStack架構。大家都說OpenStack太復雜了,如下圖是OpenStack的一個架構圖。
OpenStack主要包括以下的模塊:
-
安全認證模塊keystone
-
計算虛擬化模塊Nova
-
存儲虛擬化模塊Cinder
-
網絡虛擬化模塊Neutron
-
鏡像管理模塊Glance
-
對象存儲模塊Swift
其中每一個模塊都包含很多的子模塊,大部分包括api模塊,調度模塊,以及具體幹活的模塊。
二、OpenStack創建虛擬機的流程很復雜
OpenStack創建一個虛擬機的流程非常復雜,這裏簡單概括一下其中的要點。
第一:AAA,也即我們常說的Authentication,Authorization,Account。
所謂的Authentication認證,就是驗證我是不是我,Authorization鑒權就是審核,雖然我是我,但是我都沒有這個權利做這個事情。
Authentication一般有兩種方式,一個是對稱加密的方式,也即用一個Token,客戶端和服務端都用這個Token進行加密和解密,一個是非對稱加密的方式,也即使用PKI,使用certificate的方式。
AWS也是有這兩種方式。
另外Authorization,則常用的是Role based access control。
有用戶,角色,租戶的概念。
例如AWS裏面有
第二: nova-api接受請求
在這裏可以幹兩件事情,rate limit,調用我不能太頻繁,quota,控制每個租戶最多能夠創建多少資源。
第三:nova-scheduler進行調度
調度分兩個過程,一個是Filtering,先將不符合要求的主機過濾掉,一個是weighting,剩下的根據主機的使用情況進行打分排名,選擇一臺機器。
第四:nova-compute真正幹活的人接收到請求,調用libvirt創建虛擬機
第五:libvirt是真正的創建虛擬機的工具,先要下載虛擬機鏡像
第六:libvirt開始定義KVM的啟動參數
第七:libvirt開始給KVM創建網絡設備
第八:libvirt啟動KVM,這裏一般會用到Cgroup對KVM的資源使用進行控制
第九:調用Cinder為虛擬機創建存儲,後端一般用Ceph
想了解Kubernetes的人是不是看到這裏已經煩了,不是講kubernetes麽?怎麽講了這麽多OpenStack?
那就再來看張圖,這個是aws創建虛擬機的知識圖譜,是不是很多類似的概念?
很多學技術的發現技術發展實在太快,從虛擬化,到OpenStack,到Docker,到Kubernetes等,怎麽學的過來,其實深入了解會發現,基礎的技術非常像,包括接下來解析的Kubernetes。
三、Kubernetes的架構相對簡單
很多人喜歡Docker,以及Docker平臺,就在於Docker非常簡單,沒有OpenStack這麽復雜的概念,很容易就能啟動一個nginx的demo。
而作為容器管理平臺,Kubernetes的架構也是比較簡單的。
客戶請求進來的時候,先進入api層,相當於nova-api,首先先要進行認證和鑒權(Authentication和Authorization),相當於keystone做的事情。
然後創建的對象會保存在etcd裏面,如果是OpenStack則在數據庫裏面。
接著進行Scheduler,將對象調度到一臺機器,相當於nova-scheduler要幹的事情。
然後每臺機器上的kubelet是真正幹活的,發現自己被調度到了,需要在自己的機器上創建容器,相當於nova-compute。
kubelet創建容器的時候,先要下載容器鏡像,nova-compute也要下載虛擬機的鏡像。
nova-compute要調用docker的接口創建容器,相當於nova-compute調用的libvirt創建KVM,docker真正的隔離使用的是cgroup,KVM也要用cgroup,docker還用到了namespace,KVM的網絡配置也會用到namespace。
docker創建好了,需要給docker配置網絡,配置存儲,libvirt也幹了這些事情。
四、kubernetes創建pod和service的過程
-
客戶端調用api接口創建pod。
-
api-server將pod創建一個對象,保存在etcd裏面。
-
scheduler不斷通過api-server查看哪些pod需要調度,然後進行調度,將調度結果返回給api-server
-
api-server將scheduler的調度結果寫入etcd中。
-
kubelet不斷查看有沒有能夠調度到自己機器上的pod,有的話調用docker的接口創建容器。
-
客戶端調用api接口創建服務。
-
api-server創建service對象寫入etcd。
-
controller不斷掃描service對應的pod。
-
controller調用api-server創建對應的訪問端點endpoint。
-
api-server將endpoint對象寫入etcd。
-
proxy不斷發現有沒有可以放在自己上面的轉發規則,如果有則創建socket監聽端口,並且創建相應的iptables規則。
五、kubernetes沒有什麽?
Kubernetes看起來比OpenStack簡單很多,其實缺少了很多的功能。
-
沒有完善租戶管理模塊,租戶隔離性不好,是否需要一個類似keystone的服務?
-
是不是需要鏡像的管理,難道不需要一個類似glance的服務?
-
鏡像存儲在哪裏,是否需要一個對象存儲的服務,類似swift?
-
kubernetes本身不管網絡,需要通過插件進行,網絡和SDN誰來管理?
-
kubernetes本身不管存儲,需要通過插件進行,大部分的存儲方案還是通過Ceph搞定。
然而,如果要做一個公有雲,至少要搞定上面的部分,如果把這些都加上去,相當於基於kubernetes重造一個OpenStack了,為什麽要重復造輪子呢?所以我們選擇OpenStack和kubernetes深入融合的解決方案。
今天飛機晚點了,本來一天一篇的,應該昨天寫完的只好淩晨完成。
接下來會解析OpenStack和kubernetes融合的方案。
其實作為公有雲還有更多的問題:
-
網絡二次虛擬化的問題
-
公網和浮動IP的問題
-
一個Kubernetes集群還是多個Kubernetes集群?
-
Kubernetes集群如果做到很大規模?
-
等等等等
也會在接下來這個系列的文章中詳細闡述
支撐大規模公有雲的Kubernetes改進與優化 (1)