基于Kubernetes打造SAE容器云

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

基于HTTP請求的進程內(nèi)隔離

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

- 精準的實現(xiàn)租戶間CPU、IO、Memory隔離

- 可以實現(xiàn)進程多租戶復用,從而達到超低成本

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

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

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

- namespace獨立性不足

- 本地讀寫支持度不好

- 容易產(chǎn)生用戶lock-in

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

1,Kubernetes的好處是什么

2,Kubernetes的不足有哪些

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

一,Kubernetes的好處

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

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

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

二,Kubernetes的不足

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

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

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

三,如何改進Kubernetes

針對k8s的不足,我們需要進行改進,首先需要改造的就是日志系統(tǒng),我們希望容器產(chǎn)生的日志可以直接推送進SAE原有日志系統(tǒng)。

容器日志推送

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

用戶看到的日志

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

負載均衡同步

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

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

網(wǎng)絡

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

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

基于SAE的特點,我們采用優(yōu)化后的NAT方案。

根據(jù)我們的需求,第一步就說要將內(nèi)外網(wǎng)流量分開,進行統(tǒng)計和控制。

Docker網(wǎng)絡

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

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

多租戶網(wǎng)絡

當網(wǎng)絡包從容器出來后,先經(jīng)過我們自己寫的TagQueue進程,TagQueue負責將網(wǎng)絡包加上租戶ID,然后網(wǎng)絡包會被Docker默認的iptables規(guī)則進行SNAT,之后這個網(wǎng)絡包就變成了一個可以在物理網(wǎng)絡中傳輸?shù)恼鎸嵕W(wǎng)絡包,目標地址為目標宿主機IP,然后當?shù)竭_目標時,宿主機網(wǎng)絡協(xié)議棧會先將該網(wǎng)絡包交給運行在宿主機上的TagQueue進程,TagQueue負責把網(wǎng)絡包解出租戶ID,然后進行判斷,是否合法,如果不合法直接丟棄,否則繼續(xù)進行Docker默認的DNAT,之后進入容器目標地址。

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

存儲

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

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

SharedStorage

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

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

總結(jié)

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

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關(guān)閱讀更多精彩內(nèi)容

  • ?Kubernetes介紹1.背景介紹云計算飛速發(fā)展- IaaS- PaaS- SaaSDocker技術(shù)突飛猛進-...
    Zero___閱讀 14,860評論 0 21
  • kubernetes 簡介 一個迅速過一遍kubernetes 非常不錯的資源:基于Kubernetes構(gòu)建Doc...
    bradyjoestar閱讀 15,354評論 2 7
  • 3月25日,網(wǎng)易云技術(shù)布道系列第三期?對話架構(gòu)師上海站的活動中,網(wǎng)易云基礎設施技術(shù)總監(jiān)張曉龍帶來了題為“網(wǎng)易云容器...
    43ce3d72fadb閱讀 909評論 0 6
  • 目錄/奔跑(目錄) 上一章/奔跑(1) 時至傍晚,空中的雪花隨著憤怒的狂風肆意地翻滾著,落在地面的雪很快地掩埋了雪...
    我是木風閱讀 824評論 11 15
  • “先別急著愛我,如果你愿意,先來嘗嘗我的怪脾氣、占有欲、自私、任性。”
    漁鯤閱讀 235評論 0 0

友情鏈接更多精彩內(nèi)容