基于Kubernetes打造SAE容器云

jopen 8年前發布 | 21K 次閱讀 SAE Kubernetes

作為國內第一個公有云計算平臺,SAE從2009年已經走過了6個年頭,積累了近百萬開發者,而一直以來SAE一直以自有技術提供超輕量級的租戶隔離,這種隔離技術實際是從用戶態和內核態hook核心函數來實現HTTP層的進程內用戶隔離:

基于Kubernetes打造SAE容器云

如圖所示,這種方式的好處是:

  • 可以實現進程多租戶復用,從而達到超低成本

  • 完全對等部署,管理方便

另外,這種模式的最大好處可以實現完全的無縫擴容,SAE自動根據HTTP等待隊列長度進行跨集群調度,用戶從1000PV到10億PV業務暴增,可以不做任何變更,早在2013年,SAE就利用這種機制成功的幫助搶票軟件完成12306無法完成的任務, 12306搶票插件拖垮美國代碼托管站GitHub

但是這種模式也有很大的弊端,最主要的弊端就是:

  • namespace獨立性不足

  • 本地讀寫支持度不好

  • 容易產生用戶lock-in

針對于此,SAE決定基于Kubernetes技術推出以Docker容器為運行環境的容器云,下面我們就以下三個方面展開討論:

  1. Kubernetes的好處是什么

  2. Kubernetes的不足有哪些

  3. 針對不足,怎么改進它

一、Kubernetes的好處

選擇一個技術,對于大型業務平臺來講,最重要的就是它的易維護性,Kubernetes由Go語言編寫,各個邏輯模塊功能比較清晰,可以很快定位到功能點進行修改,另外,Kubernetes可以非常方便的部署在CentOS上,這點對我們來講也非常重要。

Kubernetes提出一個Pod的概念,Pod可以說是邏輯上的容器組,它包含運行在同一個節點上的多個容器,這些容器一般是業務相關的,他們可以共享存儲和快速網絡通信。這種在容器層上的邏輯分組非常適合實際的業務管理,這樣用戶可以按照業務模塊組成不同的Pod,比如,以一個電商業務為例:可以把PC端網站作為一個Pod,移動端API作為另一個Pod,H5端網站再作為一個Pod,這樣每個業務都可以根據訪問量使用適當數量的Pod,并且可以根據自己的需求進行擴容和容災。

相同的Pod可以由Replication Controller來控制,這樣的設計方便Pod的擴容、縮容,特別當有Pod處于不健康的狀態時,可以快速切換至新的Pod,保證總Pod數不變,而不影響服務。這種模式保證了實際業務的穩定性。

二、Kubernetes的不足

對于目前的Kubernetes來講,無縫擴容是一個比較致命的問題,不過好在社區有大量的人力已經投入力量在開發了,截止到我寫稿的時間,基于CPU的擴容代碼已經出來,也就是用戶可以設定一個平均CPU利用率,一旦數值高于某個閾值,就觸發擴容。但當我們仔細思考這個模式時,就會發現不合理的地方:CPU利用率并不能真正反映業務的繁忙程度,也不能反映是否需要擴容。比如某些業務需要大量跟API或者后端數據庫交互,這種情況下,即使CPU利用率不高,但此時用戶的請求已經變得很慢,從而需要擴容。

再有,良好的監控一直是一個系統穩定運行的前提,但Kubernetes顯然目前做的不夠,先不說Kubernetes自身的監控,就是對于Pod的監控,默認也只是簡單的TCP Connect,顯然這對于業務層是遠遠不夠的,舉個最簡單的例子,假如某個業務因為短時間大并發訪問導致504,而此時TCP協議層的鏈接是可以建立的,但顯然業務需要擴容。

還有一些其他的功能,不能算是不足,但在某些方面并不適用于SAE,比如Kube-Proxy,主要是通過VIP做三層NAT打通Kubernetes內部所有網絡通信,以此來實現容器漂IP,這個理念很先進,但有一些問題,首先是NAT性能問題,其次是所有網絡走VIP NAT,但是Kubernetes是需要和外部環境通信的,SAE容器云需要和SAE原有PaaS服務打通網絡,舉個例子,用戶利用容器云起了一組Redis的Pod,然后他在SAE上的應用需要訪問這個Pod,那么如果訪問Pod只能通過VIP的話,將會和原有SAE的網絡訪問產生沖突,這塊需要額外的技巧才能解決。所以我們覺得Kube-Proxy不太適合。

三、如何改進Kubernetes

針對Kubernetes的不足,我們需要進行改進,首先需要改造的就是日志系統,我們希望容器產生的日志可以直接推送進SAE原有日志系統。

基于Kubernetes打造SAE容器云

如上圖所示,我們將容器的stdout、stderr通過log format模塊重定向分發到SAE的日志中心,由日志中心匯總后進行分析、統計、計費,并最終展現在用戶面板,用戶可以清晰的看到自己業務的訪問日志、debug日志、容器啟動日志以及容器的操作日志。

(點擊放大圖像)

基于Kubernetes打造SAE容器云

其次,既然我們不使用Kube-Proxy的VIP模式,那么我們需要將Pod對接到SAE的L7負載均衡服務下面,以實現動態擴容和容災。

基于Kubernetes打造SAE容器云

etcd watcher監控etcd里pod路徑下的文件變更事件,得到事件取配置文件處理,判斷配置文件里狀態更新,將容器對應關系的變化同步到SAE Load Balance,Load Balance會在共享內存中cache這些關系,并且根據實際的用戶請求的HTTP Header將請求forward到相應的Pod的對外端口上。當用戶手工增加Pod時,Watcher會在100毫秒內將新增的Pod的映射關系同步到Load Balance,這樣請求就會分配到新增的Pod上了。

當然,對于云計算平臺來講,最重要的還是網絡和存儲,但很不幸,Kubernetes在這兩方面都表現的不夠好。

網絡

首先,我們來看對于網絡這塊PaaS和IaaS的需求,無論是IaaS還是PaaS,租戶間隔離都是最基本的需求,兩個租戶間的網絡不能互通,對于PaaS來講,一般做到L3基本就可以了,因為用戶無法生成L2的代碼,這個可以利用CAP_NET_RAW來控制;而對于IaaS來講,就要做到L2隔離,否則用戶可以看到別人的mac地址,然后很容易就可以構造二層數據幀來攻擊別人。對于PaaS來講,還需要做L4和L7的隔離處理,比如PaaS的網絡入口和出口一般都是共享的,比如對于出口而言,IaaS服務商遇到問題,可以簡單粗暴的將用戶出口IP引入黑洞即可,但對于PaaS而言,這樣勢必會影響其他用戶,所以PaaS需要針對不同的應用層協議做配額控制,比如不能讓某些用戶的抓取電商行為導致所有用戶不能訪問電商網站。

目前主流的Docker平臺的網絡方案主要由兩種,Bridge和NAT,Bridge實際將容器置于物理網絡中,容器拿到的是實際的物理內網IP,直接的通信和傳統的IDC間通信沒有什么區別。而NAT實際是將容器內的網絡IP:Port映射為物理實際網絡上的IP:Port,優點是節約內網IP,缺點是因為做NAT映射,速度比較慢。

基于SAE的特點,我們采用優化后的NAT方案。

根據我們的需求,第一步就說要將內外網流量分開,進行統計和控制。

基于Kubernetes打造SAE容器云

如圖所示,在容器中通過eth0和eth1分布pipe宿主機的docker0外網和docker1內網bridge,將容器的內外網流量分開,這樣我們才能對內外網區分對待,內網流量免費,而外網流量需要計費統計,同時內外網流量都需要QoS。

第二步就是要實現多租戶網絡隔離,我們借鑒IaaS在vxlan&gre的做法,通過對用戶的數據包打tag,從而標識用戶,然后在網路傳輸中,只允許相同在同一租戶之間網絡包傳輸。

基于Kubernetes打造SAE容器云

當網絡包從容器出來后,先經過我們自己寫的TagQueue進程,TagQueue負責將網絡包加上租戶ID,然后網絡包會被Docker默認的iptables規則進行SNAT,之后這個網絡包就變成了一個可以在物理網絡中傳輸的真實網絡包,目標地址為目標宿主機IP,然后當到達目標時,宿主機網絡協議棧會先將該網絡包交給運行在宿主機上的TagQueue進程,TagQueue負責把網絡包解出租戶ID,然后進行判斷,是否合法,如果不合法直接丟棄,否則繼續進行Docker默認的DNAT,之后進入容器目標地址。

除去Pod間的多租戶網絡,對外網絡部分,SAE容器云直接對接SAE標準的流量控制系統、DDOS防攻擊系統、應用防火墻系統和流量加速系統,保證業務的對外流量正常

存儲

對于業務來講,對存儲的敏感度甚至超過了網絡,因為幾乎所有業務都希望在容器之上有一套安全可靠高速的存儲方案,對于用戶的不同需求,容器云對接了SAE原有PaaS服務的Memcache、MySQL、Storage、KVDB服務,以滿足緩存、關系型數據庫、對象存儲、鍵值存儲的需求。

為了保證Node.js等應用在容器云上的完美運行,容器云還勢必引入一個類似EBS的彈性共享存儲,以保證用戶在多容器間的文件共享。針對這種需求,Kubernetes并沒有提供解決方案,于是SAE基于GlusterFS改進了一套分布式共享文件存儲SharedStorage來滿足用戶。

基于Kubernetes打造SAE容器云

如圖所示,以4個節點(brick)為例,兩兩一組組成distributed-replicated volume提供服務,用戶可以根據需求創建不同大小的SharedStorage,并選擇掛載在用戶指定的文件目錄,mount之后,就可以像本地文件系統一樣使用。我們針對GlusterFS的改進主要針對三個方面:1,增加了統計,通過編寫自己的translator模塊加入了文件讀寫的實時統計;2,增加了針對整個集群的監控,能夠實時查看各個brick、volume的狀態;3,通過改寫syscall table來hook IO操作,并執行容器端的IO Quota,這樣防止某個容器內的應用程序惡意執行IO操作而導致其他用戶受影響。

通過SharedStorage服務,用戶可以非常方便的就實現容器熱遷移,當物理機宕機后,保留在SharedStorage數據不會丟失,Kubernetes的replication controller可以快速在另外一個物理節點上將容器重新運行起來,而這個業務不受影響。

總結

Kubernetes是一個非常優秀的Docker運行框架,相信隨著社區的發展,Kubernetes會越來越完善。當然,因為SAE之前有比較完備的技術儲備,所以我們有能力針對Kubernetes目前的不足做大量的改進,同時,也歡迎大家來SAE體驗運容器平臺, http://www.sinacloud.com/sc2.html

感謝郭蕾對本文的策劃和審校。

給InfoQ中文站投稿或者參與內容翻譯工作,請郵件至editors@cn.infoq.com。也歡迎大家通過新浪微博(@InfoQ,@丁曉昀),微信(微信號: InfoQChina )關注我們。

來自: http://www.infoq.com/cn/articles/create-sae-container-cloud-based-on-kubernetes

 本文由用戶 jopen 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。
 轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。
 本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!