京東如何打造K8s全球最大集羣支撐萬億電商交易

在過去一年裏,Kubernetes以其架構簡潔性和靈活性,流行度持續快速上升,咱們有理由相信在不遠的將來,Kubernetes將成爲通用的基礎設施標準。而京東早在2016年年末上線了京東新一代容器引擎平臺JDOS2.0,成功從Openstack切換到JDOS2.0的Kubernetes技術棧,打造了完整高效的PaaS平臺。數據庫

6月28日京東基礎架構部技術總監、集羣技術部負責人鮑永成受邀出席了Rancher Labs舉辦的Container Day 2018容器技術大會,並作了題爲《京東如何打造kubernetes全球最大集羣支撐萬億電商交易》的主題演講,本文根據演講內容整理而成。緩存

鮑永成,2013年加入京東,負責京東容器平臺JDOS研發工做,帶領團隊完成京東容器大規模落地戰略,全量承載京東所有在線系統、中間件、數據庫以及大數據離線計算任務。目前聚焦在京東JDOS2.0、阿基米德調度平臺(特別搶佔式智能數據中心調度系統、京東大幅提高數據中心資源使用率的利器)、「雲+端」線下門店生態基礎設施以及新一代數據中心研發工做。服務器

在演講中鮑永成分享了京東在大規模實際生產過程對Kubernetes作深刻重構的經驗,以及京東如何圍繞K8s啓動一些內部新項目,服務JDOS2.0大規模生產環境穩定高效運行。網絡

感謝Rancher邀請咱們來作京東在容器方面的分享。京東的分享可能跟業內的不少作向外輸出的公司有點不同,咱們的容器主要是自用。京東的數據中心如今規模已經比較大,實際上咱們用Kubernetes或者是之前用Openstack的思路徹底是克隆谷歌數據中心管理的理念。架構

容器生態建設負載均衡

其實數據中心就是圍繞着幾個東西來講:服務器、網絡以及一些基礎軟件,剩下的就是集羣的管理。這裏要說明一下,咱們認爲基礎軟件是數據中心很是重要的一個環節,好比,域名解析、負載均衡、時鐘這些東西,雖然Kubernetes管理了整個集羣,可是這些東西它依然沒有。也就是說,要是想把它用得很是好的話,這些軟件也要進行一些適當的變革。運維

京東在使用Kubernetes管理大數據中心的時候,也圍繞着Kubernetes在咱們內部的數據中心建了不少生態。首先是適合容器化的DNS,以及適合容器化的負載均衡,還有適合容器化的文件系統、鏡像中心等等。這裏面特別要說明一點,就是DNS跟LB,Kubernetes 1.9合入了高性能的負載均衡。分佈式

若是在大規模生產環境中,高性能的負載均衡是必不可少的,但這個負載均衡又涉及到另一些問題。首先,要跟現有的數據中心適配,京東自主研發了一套負載均衡以及DNS。雖然社區裏有CoreDNS等等,可是這些DNS存在一個問題,就像昨天某廠的一個故障那樣,你把全部的東西這個引導這個,那個引導那個。若是你的DNS不在容器內的話,帶來的後果是很難料想的。由於京東容器已經發展了不少年,數據中心也比較大,咱們單個Kubernetes集羣可以作到8000到10000臺。由於咱們的機器實在太多,若是不作大集羣的話,人力管理的投入上會很是大。後面我會解釋怎麼作到這麼大規模的集羣。性能

京東容器化的數據中心建設已經四五年了,已經比較穩定了,雖然咱們的Kubernetes還比較老,是1.6版本,可是咱們已經有不少改進,咱們如今的重點就是往阿基米德,也就是往數據中心的資源調度這個方向發展。去年雙十一的時候阿基米德已經上線了,Kubernetes使用到後期的時候,你會發現Kubernetes並不能解決數據中心資源使用率的問題,它其實僅僅解決了你的發佈,或者是管理資源的容器這方面的一些東西。測試

上圖是咱們數據中心的基礎架構,其實比較傳統,咱們會把負載均衡、域名,以及咱們包的這個Kubernetes的API統一抽象出來,整個就是一套。而後在每一個數據中心部署若干套Kubernetes集羣,每個Kubernetes集羣,會管理三個物理Pod,大概是一萬臺的規模。

爲了配合這個規模,咱們作了一些工做。DNS最先的時候,尚未CoreDNS來適配,你們知道每一個數據中心最老的DNS是bind9,適配起來是很是痛苦的,它缺API,缺不少東西。因此咱們就本身研發了一套基於Etcd的分佈式DNS,當時提供了RestfulAPI,直接對接的Kubernetes的watch,這樣的話咱們就可以作一個很是好的適配。可是後來咱們發現一個問題,原來你有可能10萬臺物理機,也就假設就是你的hostname的解析也就10萬個,如今不同了,一臺物理機是100多個容器,即你增加了100倍。這時運維解析的請求量會激增,增加以後會帶來一個問題,抖動、延遲都很是大,間接的就影響了你的業務的TP響應。所以咱們後來又把咱們域名解析的服務,改爲了DBTK的服務,如今的性能是bind9的19倍,是CoreOS的60多倍,每秒查詢率能衝到800萬QBS。

化繁爲簡Kubernetes重構

有人問,京東作一個這麼大的Kubernetes集羣,是否是特別複雜特別容易出錯。確實,若是你的集羣很是多,假設你有50個集羣,那麼你誤操做的機率可能就是這50的機率相加。所以京東會把整個Kubernetes的集羣作減法,並無作加法,固然這是表明京東的一家之言了,由於咱們是自用,並非往外賣,因此咱們主要是作減法,以適合咱們使用。

爲了適用上萬臺Server的這種規模,最大的問題就是API的負載容易崩潰。好比你把config-map存到etcd裏面去,這個設計自己就是有問題的。若是你的規模比較大的話,必定要去改,若是不改,你的集羣很快就會崩潰。其實咱們的作法其實還比較傳統,就是採用一些緩存技術,就好比說config-map咱們壓根是不會放在etcd裏去的。由於若是你把config-map放到etcd裏去的話,首先假設有一個用戶,給你傳一百個20M的配置文件,你就完蛋了。

其次,京東對controller也作了不少重構,雖然社區提供了不少controller,但我能夠保證,這些controller絕對沒有作嚴格的關聯性測試,也就是說有些controller之間互相是有影響的。建議啓用任何一個controller前都要作嚴格的分析跟測試。想作大集羣的Kubernetes,必須得去改,並且是作減法式的改。

還有一點,Kubernetes號稱有各式各種功能,我可能要潑一下冷水。京東不少東西的確是基於Kubernetes建設起來的,Kubernetes對咱們的幫助很是大,可是它也不是萬能的。

Kubernetes號稱的deployment、金絲雀發佈等等一切都很是美好,可是我來自京東基礎架構部門,基礎部門要服務業務,而業務會給你提不少需求,第一次你聽上去可能以爲這需求很是扯,可是你跟他仔細溝通以後,你會發現人家的需求是很是合理的。好比說,他說你金絲雀發佈的時候,副本數隨機的挑幾個,升級了50%,但有的業務方會要求就要升級某一個特定IP。他不是對這個IP特別有感情,而是由於他配了不少host,除了有研發還有測試等等,因此你不得不去面臨這個問題,像IP不變等等這樣的一些需求就會蹦出來,咱們都要知足他,才能繼續往下走。

還有好比說你的節點被物理故障重啓等等,這個時候你要充分的考慮是先拉起新調度過來的容器,仍是先拉起原來老的容器,這些策略都要針對你本身的業務去改變。

還有,好比有人說京東大促的時候,咱們Kubenetes整個的彈性速度很是快等等。可是我能夠向你保證,若是真正是那種流量高峯瞬間來的時候,這個彈性是絕對跟不上的。由於等你還沒彈完,老的已經被打死了,彈幾個死幾個,因此通常來講,你要用更多的實例,用調度的方式來作,而不是說經過scale out這種彈來作,來不及的。

剛纔也提到這些策略IP不變,還有咱們這有一個頗有意思的東西,就是支持容器的rebuild。咱們的資源使用率,經過阿基米德調度以後,咱們的資源使用率很是緊張,由於少買了不少機器,同時業務又在不斷地增加,這個時候咱們資源的限額都會被耗盡,在某些狀況下甚至調度器也無能爲力。

這怎麼辦?咱們採起了一種古老的方法,跳過調度器,進行本地rebuild。由於你的調度有的在排隊,有的depending,可是有一些業務在發佈的時候,他會提出一個問題,我原來有100個容器,我發佈完以後只剩80了,另外20個容器的資源被別的業務搶走了,這是不能接受的,因此咱們也有了這種所謂的優先rebuild,就是就地rebuild,這會帶來不少好處。

這麼作最明顯的一個好處,就是拉鏡像至少省了一些時間。還有一個明顯的好處是,雖然在數據中心依然很複雜,但當業務部署在某一臺容器機器上以後,調用的依賴、調用數據庫的鏈路都是通過了大量壓測的,已達到相對最優的狀態。若是你今天把這容器從pod1搬到pod2,我說物理pod,從房間1搬到房間2去了,那可能會帶來抖動或者等等狀況。固然這並不表明你損失了Kubernetes的不少特性。

補充前面的一點,咱們的deployment作了大量定製,原生的deployment其實仍是很難知足這樣的要求。好比說在線上,由於是面向生產環境,可是生產環境不會那麼美好。首先業務,可能上100個容器就有兩個容器,它的響應不好,這個時候要去排查或者要去進行其餘的操做,這個時候用deployment作不到,由於一升級就沒了。而咱們,讓它能夠指定把這兩個停掉,或者是其餘操做,反正就是可以指定,就至關於你要改一些東西,改動量不大,只是在它原來基礎之上改。

阿基米德調度器

下面說說咱們目前的工做重點。京東整個數據中心規模很大,有老有新,總體的資源使用率會有明顯的波峯波谷。好比上圖黑底圖上藍色的線,1點到6點時中國整個互聯網的流量都比較低,可是到8點之後流量就開始逐漸攀升。那麼1點到6點是一個很是浪費的階段,由於咱們有大量的計算資源,這時候咱們就能夠跟大數據產生互補,把在線應用的波谷算力貢獻給大數據作離線計算,恰好大數據也是後半夜,相對來講離線任務更多,由於次日早上要出報表,因而咱們作了一個融合的混合部署的項目,就叫阿基米德,就是把大數據的業務給調到在線業務的平臺上去。

這裏面就涉及到一個問題,就是隔離性。你們都以爲Docker的隔離性已經很優秀了,其實並不是如此,它的隔離性沒有你們想象的那麼好,你看到的隔離都是Namespace的隔離,真正的性能隔離其實並無徹底作到位。例如內存回收,它實際上是操做系通通一進行回收的。好比上面10個容器有5個容器狂讀小文件,這時候忽然內存已經到必定閥值了,它就要作一次slab回收。一旦slab回收,它就都被block住了,其餘的在線業務都會被卡住,雖然只是毫秒級的,可是會有毛刺,業務就會來問你發生了什麼。特別是在線大數據進來以後,這個問題就會被無限放大,所以在這塊你要作適當的改動。京東作得比較早,從2013年就開始作容器,在過去幾年咱們在這塊已經作了不少工做。

還有另一個,你們也都感同身受。業務說我須要100個容器,每一個容器八個核,其實以後發現每一個容器只跑了不到10%的CPU,這種狀況是有可能的。那怎麼辦?你不能粗暴地只給業務兩個核,出問題誰負責?那怎麼辦?咱們就告訴業務咱們給了他八個核(其實沒有),只要不出事就好了,出了事解釋也無用。這會帶來一個巨大的收益,就像上圖,綠色的部分是咱們給的CPU,紅色是實際使用的,那咱們至少給他砍一半。這樣作了以後你就會發現,即便一年不買機器,機器也是夠的。

調度方面的問題,京東整個數據中心都是用Kubenretes來管,咱們取名爲JDOS,即JD Datacenter OS,封包了Kubernetes而後作了大量的定製。往上層看,JDOS支持京東的在線業務。在線業務在2016年6·18以前所有遷完了。而後2017年雙十一的時候數據庫所有都遷完了,到2018年初的時候,咱們基本上像中間件類的也都大部分遷上來了,也就是說如今咱們除了單純的存儲圖片,還在用物理機那種存儲型的服務器以外,剩下的全在容器上,如今京東已經看不到物理機了。如今正在作的就是把大數據也往上面導。這會帶來一個很是好的收益。

可是把大數據及不少其餘業務放上JDOS以後咱們發現,整個調度變得很是複雜,原來的調度器只是考慮哪一臺適合放就能夠了,用一句話說,它只負責殺,不負責埋。這會帶來一個問題,容器運行以後,帶來的影響Kubernetes是無能爲力的,除非崩潰了,它給你再從新拉副本等等。這看上去會很美好,實際上業務會每天投訴你。

爲解決這一問題,咱們應用上線的時候會要選優先級,若是你的優先級不高的話,有可能會被優先級高的驅逐掉,至關於咱們單獨對Kubernetes從新作一個東西,即咱們的驅逐器。驅逐器會對pod打上不少標籤,好比優先級、容忍度、副本數等等(例如只有一個副本的話,它優先級再低也不能殺)。這很像OM的排序,當宿主機的CPU、內存load達到必定上限的時候,咱們就會啓動這種排序,很快地把它排出來,立馬就驅逐,並且驅逐以後,會告訴調度器不要再往這臺上調了。由於有可能資源滿了,它又給調回來了,你又給驅逐,就造成一個死循環了。其實基本的理念也很是簡單,就是保障優先級的系統,大數據是最早優先級,可是在線業務的話,也要往下放,這樣就能在有限資源的狀況下發揮最大的做用,特別是大促的時候,若是都是靠買機器來支撐的話,這是很是恐怖的一件事情。由於每次大促咱們都要按20倍來估,這要買多少機器啊。

總 結

最後我想分享一些經驗與心得體會。

京東最先是Openstack,在2016年切換到了Kubernetes,這兩種系統我一直作下來的,個人感覺就是, Kubernetes正在往Openstack這條路上走,越作越龐大,這是一個很是大的問題。誠然,它有不少feature要加,這個也能夠理解,可它仍是得拆,拆成很是小的模塊來作。像如今CNI、CRI、CSI這些模塊的拆離應該是比較好的一個開始。Kubernetes在中小規模集羣是沒有問題的,可是它確定沒有官方號稱的那樣5000臺沒問題,若是是很是大的規模的話,確定要去改,不然的話會崩潰。咱們在早期的時候,上了一些非重要的系統,經歷了很是痛苦的一段時間,它時常崩掉了。

有時候Etcd跑着跑着就發現版本差別愈來愈大,那隻能把另外兩個幹掉,把另一個副本用來複制另外兩份,這會帶來巨大的問題。Etcd的運維如今應該沒有特別成熟的一些方案,它不像數據庫有很成熟的運維方案,畢竟數據放在裏面,若是它崩了,數據就很難找回來,這是很是麻煩的一件事。

還有它的API,由於它是長連接,通常的負載均衡要特別注意起API的時候不能一個一個起,起完了它都來連,搞很差都堆到一臺上去了,會致使負載不均衡,因此正常來講要先把API起好,再去起Kubernetes,這樣負載均衡纔會起到做用。

另外,你們必定要特別注意Kubernetes對心跳的判斷,由於它發生not ready的機率過高了。一旦發生節點not ready的話,會產生一系列難以預料的狀態,好比網絡抖動,某臺交換機壞了,有可能它就會這樣。因此咱們建議心跳檢測這一塊儘可能用另一套系統來作,把你檢測的結果反饋給Kubernetes,這樣可能會更好一些。

這就是我今天演講,謝謝你們。

後續Rancher將會繼續爲你們帶來更多大會演講實錄,請保持關注Rancher 公衆號的最新推送~

相關文章
相關標籤/搜索