<ul id="qxxfc"><fieldset id="qxxfc"><tr id="qxxfc"></tr></fieldset></ul>


      背景

      美團(tuán)的容器集群管理平臺(tái)叫做HULK
      。漫威動(dòng)畫里的HULK在發(fā)怒時(shí)會(huì)變成“綠巨人”,它的這個(gè)特性和容器的“彈性伸縮”很像,所以我們給這個(gè)平臺(tái)起名為HULK。貌似有一些公司的容器平臺(tái)也叫這個(gè)名字,純屬巧合。


      2016年,美團(tuán)開(kāi)始使用容器,當(dāng)時(shí)美團(tuán)已經(jīng)具備一定的規(guī)模,在使用容器之前就已經(jīng)存在的各種系統(tǒng),包括CMDB、服務(wù)治理、監(jiān)控告警、發(fā)布平臺(tái)等等。我們?cè)谔剿魅萜骷夹g(shù)時(shí),很難放棄原有的資產(chǎn)。所以容器化的第一步,就是
      打通容器的生命周期和這些平臺(tái)的交互,例如容器的申請(qǐng)/創(chuàng)建、刪除/釋放、發(fā)布、遷移等等。然后我們又驗(yàn)證了容器的可行性,證實(shí)容器可以作為線上核心業(yè)務(wù)的運(yùn)行環(huán)境。




      2018年,經(jīng)過(guò)兩年的運(yùn)營(yíng)和實(shí)踐探索,我們對(duì)容器平臺(tái)進(jìn)行了一次升級(jí),這就是容器集群管理平臺(tái)HULK 2.0。
      ?●??把基于OpenStack的調(diào)度系統(tǒng)升級(jí)成容器編排領(lǐng)域的事實(shí)標(biāo)準(zhǔn)Kubernetes(以后簡(jiǎn)稱K8s)。
      ?●??提供了更豐富可靠的容器彈性策略。
      ?●??針對(duì)之前在基礎(chǔ)系統(tǒng)上碰到的一些問(wèn)題,進(jìn)行了優(yōu)化和打磨。


      美團(tuán)當(dāng)前的容器使用狀況是:線上業(yè)務(wù)已經(jīng)超過(guò)3000多個(gè)服務(wù),容器實(shí)例數(shù)超過(guò)30000個(gè),很多大并發(fā)、低延時(shí)要求的核心鏈路服務(wù),已經(jīng)穩(wěn)定地運(yùn)行在HULK之上。本文主要介紹我們?cè)谌萜骷夹g(shù)上的一些實(shí)踐,屬于基礎(chǔ)系統(tǒng)優(yōu)化和打磨。

      美團(tuán)容器平臺(tái)的基本架構(gòu)

      首先介紹一下美團(tuán)容器平臺(tái)的基礎(chǔ)架構(gòu),相信各家的容器平臺(tái)架構(gòu)大體都差不多。





      首先,容器平臺(tái)對(duì)外對(duì)接服務(wù)治理、發(fā)布平臺(tái)、CMDB、監(jiān)控告警等等系統(tǒng)。通過(guò)和這些系統(tǒng)打通,容器實(shí)現(xiàn)了和虛擬機(jī)基本一致的使用體驗(yàn)。研發(fā)人員在使用容器時(shí)可以和使用VM一樣,不需要改變?cè)瓉?lái)的使用習(xí)慣。


      此外,容器提供彈性擴(kuò)容能力,能根據(jù)一定的彈性策略動(dòng)態(tài)增加和減少服務(wù)的容器節(jié)點(diǎn)數(shù),從而動(dòng)態(tài)地調(diào)整服務(wù)處理能力。這里還有個(gè)特殊的模塊——“服務(wù)畫像”,它的主要功能是通過(guò)對(duì)服務(wù)容器實(shí)例運(yùn)行指標(biāo)的搜集和統(tǒng)計(jì),更好的完成調(diào)度容器、優(yōu)化資源分配。
      比如可以根據(jù)某服務(wù)的容器實(shí)例的CPU、內(nèi)存、IO等使用情況,來(lái)分辨這個(gè)服務(wù)屬于計(jì)算密集型還是IO密集型服務(wù),在調(diào)度時(shí)盡量把互補(bǔ)的容器放在一起。

      再比如,我們可以知道某個(gè)服務(wù)的每個(gè)容器實(shí)例在運(yùn)行時(shí)會(huì)有大概500個(gè)進(jìn)程,我們就會(huì)在創(chuàng)建容器時(shí),給該容器加上一個(gè)合理的進(jìn)程數(shù)限制(比如最大1000個(gè)進(jìn)程
      ),從而避免容器在出現(xiàn)問(wèn)題時(shí),占用過(guò)多的系統(tǒng)資源。如果這個(gè)服務(wù)的容器在運(yùn)行時(shí),突然申請(qǐng)創(chuàng)建20000個(gè)進(jìn)程,我們有理由相信是業(yè)務(wù)容器遇到了Bug,通過(guò)之前的資源約束對(duì)容器進(jìn)行限制,并發(fā)出告警,通知業(yè)務(wù)及時(shí)進(jìn)行處理。

      往下一層是“容器編排”和“鏡像管理
      ”。容器編排解決容器動(dòng)態(tài)實(shí)例的問(wèn)題,包括容器何時(shí)被創(chuàng)建、創(chuàng)建到哪個(gè)位置、何時(shí)被刪除等等。鏡像管理解決容器靜態(tài)實(shí)例的問(wèn)題,包括容器鏡像應(yīng)該如何構(gòu)建、如何分發(fā)、分發(fā)的位置等等。

      最下層是我們的容器運(yùn)行時(shí),美團(tuán)使用主流的Linux+Docker容器方案,HULK Agent是我們?cè)诜?wù)器上的管理代理程序。

      把前面的“容器運(yùn)行時(shí)”具體展開(kāi),可以看到這張架構(gòu)圖,按照從下到上的順序介紹:



      ?●??最下層是CPU、內(nèi)存、磁盤、網(wǎng)絡(luò)這些基礎(chǔ)物理資源。
      ?●??往上一層,我們使用的是CentOS
      7作為宿主機(jī)操作系統(tǒng),Linux內(nèi)核的版本是3.10。我們?cè)贑entOS發(fā)行版默認(rèn)內(nèi)核的基礎(chǔ)上,加入一些美團(tuán)為容器場(chǎng)景研發(fā)的新特性,同時(shí)為高并發(fā)、低延時(shí)的服務(wù)型業(yè)務(wù)做了一些內(nèi)核參數(shù)的優(yōu)化。
      ?●??再往上一層,我們使用的是CentOS發(fā)行版里自帶的Docker,當(dāng)前的版本是1.13,同樣,加入了一些我們自己的特性和增強(qiáng)。HULK
      Agent是我們自己開(kāi)發(fā)的主機(jī)管理Agent,在宿主機(jī)上管理Agent。Falcon
      Agent同時(shí)存在于宿主機(jī)和容器內(nèi)部,它的作用是收集宿主機(jī)和容器的各種基礎(chǔ)監(jiān)控指標(biāo),上報(bào)給后臺(tái)和監(jiān)控平臺(tái)。
      ?●??最上一層是容器本身。我們現(xiàn)在主要支持CentOS 6和CentOS 7兩種容器。在CentOS 6中有一個(gè)container
      init進(jìn)程,它是我們開(kāi)發(fā)容器內(nèi)部的1號(hào)進(jìn)程,作用是初始化容器和拉起業(yè)務(wù)進(jìn)程。在CentOS
      7中,我們使用了系統(tǒng)自帶的systemd作為容器中的1號(hào)進(jìn)程。我們的容器支持各種主流編程語(yǔ)言,包括Java、Python、Node.js、C/C++等等。在語(yǔ)言層之上是各種代理服務(wù),包括服務(wù)治理的Agent、日志Agent、加密Agent等等。同時(shí),我們的容器也支持美團(tuán)內(nèi)部的一些業(yè)務(wù)環(huán)境,例如set信息、泳道信息等,配合服務(wù)治理體系,可以實(shí)現(xiàn)服務(wù)調(diào)用的智能路由。

      美團(tuán)主要使用了CentOS系列的開(kāi)源組件,因?yàn)槲覀冋J(rèn)為Red Hat有很強(qiáng)的開(kāi)源技術(shù)實(shí)力,比起直接使用開(kāi)源社區(qū)的版本,我們希望Red
      Hat的開(kāi)源版本能夠幫助解決大部分的系統(tǒng)問(wèn)題。我們也發(fā)現(xiàn),即使部署了CentOS的開(kāi)源組件,仍然有可能會(huì)碰到社區(qū)和Red
      Hat沒(méi)有解決的問(wèn)題。從某種程度上也說(shuō)明,國(guó)內(nèi)大型互聯(lián)公司在技術(shù)應(yīng)用的場(chǎng)景、規(guī)模、復(fù)雜度層面已經(jīng)達(dá)到了世界領(lǐng)先的水平,所以才會(huì)先于社區(qū)、先于Red
      Hat的客戶遇到這些問(wèn)題。

      容器遇到的一些問(wèn)題

      在容器技術(shù)本身,我們主要遇到了4個(gè)問(wèn)題:隔離、穩(wěn)定性、性能和推廣。
      ?●??
      隔離——包含兩個(gè)層面:第一個(gè)問(wèn)題是,容器能不能正確認(rèn)識(shí)自身資源配置;第二個(gè)問(wèn)題是,運(yùn)行在同一臺(tái)服務(wù)器上的容器會(huì)不會(huì)互相影響。比如某一臺(tái)容器的IO很高,就會(huì)導(dǎo)致同主機(jī)上的其它容器服務(wù)延時(shí)增加。
      ?●??穩(wěn)定性:這是指在高壓力、大規(guī)模、長(zhǎng)時(shí)間運(yùn)行以后,系統(tǒng)功能可能會(huì)出現(xiàn)不穩(wěn)定的問(wèn)題,比如容器無(wú)法創(chuàng)建、刪除,因?yàn)檐浖?wèn)題發(fā)生卡死、宕機(jī)等問(wèn)題。
      ?●??
      性能:在虛擬化技術(shù)和容器技術(shù)比較時(shí),大家普遍都認(rèn)為容器的執(zhí)行效率會(huì)更高,但是在實(shí)踐中,我們遇到了一些特例:同樣的代碼在同樣配置的容器上,服務(wù)的吞吐量、響應(yīng)時(shí)延反而不如虛擬機(jī)。
      ?●??
      推廣:當(dāng)我們把前面幾個(gè)問(wèn)題基本上都解決以后,仍然可能會(huì)碰到業(yè)務(wù)不愿意使用容器的情況,其中原因一部分是技術(shù)因素,例如容器接入難易程度、周邊工具、生態(tài)等都會(huì)影響使用容器的成本。推廣也不是一個(gè)純技術(shù)問(wèn)題,跟公司內(nèi)部的業(yè)務(wù)發(fā)展階段、技術(shù)文化、組織設(shè)置和KPI等因素都密切相關(guān)。
      容器的實(shí)現(xiàn)



      容器本質(zhì)上是把系統(tǒng)中為同一個(gè)業(yè)務(wù)目標(biāo)服務(wù)的相關(guān)進(jìn)程合成一組,放在一個(gè)叫做namespace的空間中,同一個(gè)namespace中的進(jìn)程能夠互相通信,同時(shí)看不見(jiàn)其他namespace中的進(jìn)程。每個(gè)namespace可以擁有自己獨(dú)立的主機(jī)名、進(jìn)程ID系統(tǒng)、IPC、網(wǎng)絡(luò)、文件系統(tǒng)、用戶等等資源,在某種程度上,實(shí)現(xiàn)了一個(gè)簡(jiǎn)單的虛擬:讓一個(gè)主機(jī)上可以同時(shí)運(yùn)行多個(gè)互不感知的系統(tǒng)。

      此外,為了限制namespace對(duì)物理資源的使用,對(duì)進(jìn)程能使用的CPU、內(nèi)存等資源需要做一定的限制,這就是Cgroup技術(shù),Cgroup是Control
      group的意思。比如我們常說(shuō)的4c4g的容器,實(shí)際上是限制這個(gè)容器namespace中所用的進(jìn)程,最多能夠使用4核的計(jì)算資源和4GB的內(nèi)存。

      簡(jiǎn)而言之,Linux內(nèi)核提供namespace完成隔離,Cgroup完成資源限制。namespace+Cgroup構(gòu)成了容器的底層技術(shù)(
      rootfs是容器文件系統(tǒng)層技術(shù))。

      美團(tuán)的解法、改進(jìn)和優(yōu)化

      隔離


      之前一直和虛擬機(jī)打交道,但直到用上容器,才發(fā)現(xiàn)在容器里面看到的CPU、Memory的信息都是服務(wù)器主機(jī)的信息,而不是容器自身的配置信息,直到現(xiàn)在,社區(qū)版的容器還是這樣。比如一個(gè)4c4g的容器,在容器內(nèi)部可以看到有40顆CPU、196GB內(nèi)存的資源,這些資源其實(shí)是容器所在宿主機(jī)的信息。這給人的感覺(jué),就像是容器的“自我膨脹”,覺(jué)得自己能力很強(qiáng),但實(shí)際上并沒(méi)有,而且還會(huì)帶來(lái)很多問(wèn)題。





      上圖是一個(gè)內(nèi)存信息隔離的例子。獲取系統(tǒng)內(nèi)存信息時(shí),社區(qū)Linux無(wú)論在主機(jī)上還是在容器中,內(nèi)核都是統(tǒng)一返回主機(jī)的內(nèi)存信息,如果容器內(nèi)的應(yīng)用,按照它發(fā)現(xiàn)的宿主機(jī)內(nèi)存來(lái)進(jìn)行配置的話,實(shí)際資源是遠(yuǎn)遠(yuǎn)不夠的,導(dǎo)致的結(jié)果就是:系統(tǒng)很快會(huì)發(fā)生OOM異常。

      我們做的隔離工作,是在容器中獲取內(nèi)存信息時(shí),內(nèi)核根據(jù)容器的Cgroup信息返回容器的內(nèi)存信息(類似LXCFS的工作)。




      CPU信息隔離的實(shí)現(xiàn)和內(nèi)存的類似,不再贅述,這里舉一個(gè)CPU數(shù)目影響應(yīng)用性能例子。

      大家都知道,JVM GC(垃圾對(duì)象回收)對(duì)Java程序執(zhí)行性能有一定的影響。默認(rèn)的JVM使用公式“ParallelGCThreads = (ncpus <=
      8) ? ncpus : 3 + ((ncpus * 5) / 8)”
      來(lái)計(jì)算做并行GC的線程數(shù),其中ncpus是JVM發(fā)現(xiàn)的系統(tǒng)CPU個(gè)數(shù)。一旦容器中JVM發(fā)現(xiàn)了宿主機(jī)的CPU個(gè)數(shù)(通常比容器實(shí)際CPU限制多很多
      ),這就會(huì)導(dǎo)致JVM啟動(dòng)過(guò)多的GC線程,直接的結(jié)果就導(dǎo)致GC性能下降。Java服務(wù)的感受就是延時(shí)增加,TP監(jiān)控曲線突刺增加,吞吐量下降。針對(duì)這個(gè)問(wèn)題有各種解法:
      ?●??
      顯式的傳遞JVM啟動(dòng)參數(shù)“-XX:ParallelGCThreads”告訴JVM應(yīng)該啟動(dòng)幾個(gè)并行GC線程。它的缺點(diǎn)是需要業(yè)務(wù)感知,為不同配置的容器傳不同的JVM參數(shù)。
      ?●??在容器內(nèi)使用Hack過(guò)的glibc,使JVM(通過(guò)sysconf系統(tǒng)調(diào)用
      )能正確獲取容器的CPU資源數(shù)。我們?cè)谝欢螘r(shí)間內(nèi)使用的就是這種方法。其優(yōu)點(diǎn)是業(yè)務(wù)不需要感知,并且能自動(dòng)適配不同配置的容器。缺點(diǎn)是必須使用改過(guò)的glibc,有一定的升級(jí)維護(hù)成本,如果使用的鏡像是原生的glibc,問(wèn)題也仍然存在。

      ?●??我們?cè)谛缕脚_(tái)上通過(guò)對(duì)內(nèi)核的改進(jìn),實(shí)現(xiàn)了容器中能獲取正確CPU資源數(shù),做到了對(duì)業(yè)務(wù)、鏡像和編程語(yǔ)言都透明(
      類似問(wèn)題也可能影響OpenMP、Node.js等應(yīng)用的性能)。




      有一段時(shí)間,我們的容器是使用root權(quán)限進(jìn)行運(yùn)行,實(shí)現(xiàn)的方法是在docker
      run的時(shí)候加入‘privileged=true’參數(shù)。這種粗放的使用方式,使容器能夠看到所在服務(wù)器上所有容器的磁盤,導(dǎo)致了安全問(wèn)題和性能問(wèn)題。安全問(wèn)題很好理解,為什么會(huì)導(dǎo)致性能問(wèn)題呢?可以試想一下,每個(gè)容器都做一次磁盤狀態(tài)掃描的場(chǎng)景。當(dāng)然,權(quán)限過(guò)大的問(wèn)題還體現(xiàn)在可以隨意進(jìn)行mount操作,可以隨意的修改NTP時(shí)間等等。


      在新版本中,我們?nèi)サ袅巳萜鞯膔oot權(quán)限,發(fā)現(xiàn)有一些副作用,比如導(dǎo)致一些系統(tǒng)調(diào)用失敗。我們默認(rèn)給容器額外增加了sys_ptrace和sys_admin兩個(gè)權(quán)限,讓容器可以運(yùn)行GDB和更改主機(jī)名。如果有特例容器需要更多的權(quán)限,可以在我們的平臺(tái)上按服務(wù)粒度進(jìn)行配置。




      Linux有兩種IO:Direct IO和Buffered IO。Direct IO直接寫磁盤,Duffered
      IO會(huì)先寫到緩存再寫磁盤,大部分場(chǎng)景下都是Buffered IO。

      我們使用的Linux內(nèi)核3.X,社區(qū)版本中所有容器Buffer
      IO共享一個(gè)內(nèi)核緩存,并且緩存不隔離,沒(méi)有速率限制,導(dǎo)致高IO容器很容易影響同主機(jī)上的其他容器。Buffer IO緩存隔離和限速在Linux
      4.X里通過(guò)Cgroup V2實(shí)現(xiàn),有了明顯的改進(jìn),我們還借鑒了Cgroup V2的思想,在我們的Linux
      3.10內(nèi)核實(shí)現(xiàn)了相同的功能:每個(gè)容器根據(jù)自己的內(nèi)存配置有對(duì)應(yīng)比例的IO Cache,Cache的數(shù)據(jù)寫到磁盤的速率受容器Cgroup IO配置的限制。


      Docker本身支持較多對(duì)容器的Cgroup資源限制,但是K8s調(diào)用Docker時(shí)可以傳遞的參數(shù)較少,為了降低容器間的互相影響,我們基于服務(wù)畫像的資源分配,對(duì)不同服務(wù)的容器設(shè)定不同的資源限制。除了常見(jiàn)的CPU、內(nèi)存外,還有IO的限制、ulimit限制、PID限制等等,所以我們擴(kuò)展了K8s來(lái)完成這些工作。




      業(yè)務(wù)在使用容器的過(guò)程中產(chǎn)生core
      dump文件是常見(jiàn)的事。比如C/C++程序內(nèi)存訪問(wèn)越界,或者系統(tǒng)OOM時(shí),系統(tǒng)選擇占用內(nèi)存多的進(jìn)程殺死,默認(rèn)都會(huì)生成一個(gè)core dump文件。

      社區(qū)容器系統(tǒng)默認(rèn)的core dump文件會(huì)生成在宿主機(jī)上。由于一些core dump文件比較大,比如JVM的core
      dump通常是幾個(gè)GB,或者有些存在Bug的程序,其頻發(fā)的core
      dump,很容易快速寫滿宿主機(jī)的存儲(chǔ),并且會(huì)導(dǎo)致高磁盤IO,也會(huì)影響到其他容器。還有一個(gè)問(wèn)題是:業(yè)務(wù)容器的使用者沒(méi)有權(quán)限訪問(wèn)宿主機(jī),從而拿不到dump文件進(jìn)行下一步的分析。

      為此,我們對(duì)core dump的流程進(jìn)行了修改,讓dump文件寫到容器自身的文件系統(tǒng)中,并且使用容器自己的Cgroup IO吞吐限制。

      穩(wěn)定性

      我們?cè)趯?shí)踐中發(fā)現(xiàn),影響系統(tǒng)穩(wěn)定性的主要是Linux
      Kernel和Docker。雖然它們本身是很可靠的系統(tǒng)軟件,但是在大規(guī)模、高強(qiáng)度的場(chǎng)景中,還是會(huì)存在一些Bug。這也從側(cè)面說(shuō)明,我們國(guó)內(nèi)互聯(lián)網(wǎng)公司在應(yīng)用規(guī)模和應(yīng)用復(fù)雜度層面也屬于全球領(lǐng)先。

      在內(nèi)核方面,美團(tuán)發(fā)現(xiàn)了Kernel 4.x Buffer
      IO限制的實(shí)現(xiàn)問(wèn)題,得到了社區(qū)的確認(rèn)和修復(fù)。我們還跟進(jìn)了一系列CentOS的Ext4補(bǔ)丁,解決了一段時(shí)間內(nèi)進(jìn)程頻繁卡死的問(wèn)題。




      我們碰到了兩個(gè)比較關(guān)鍵的Red Hat版Docker穩(wěn)定性問(wèn)題:
      ?●??在Docker服務(wù)重啟以后,Docker exec無(wú)法進(jìn)入容器,這個(gè)問(wèn)題比較復(fù)雜。在解決之前我們用nsenter來(lái)代替Docker
      exec并積極反饋給Red Hat。后來(lái)Red
      Hat在今年初的一個(gè)更新解決了這個(gè)問(wèn)題。https://access.redhat.com/errata/RHBA-2017:1620
      ?●??是在特定條件下Docker Daemon會(huì)Panic,導(dǎo)致容器無(wú)法刪除。經(jīng)過(guò)我們自己Debug,并對(duì)比最新的代碼,發(fā)現(xiàn)問(wèn)題已經(jīng)在Docker
      upstream中得到解決,反饋給Red
      Hat也很快得到了解決。https://github.com/projectatomic/containerd/issues/2


      面對(duì)系統(tǒng)內(nèi)核、Docker、K8S這些開(kāi)源社區(qū)的系統(tǒng)軟件,存在一種觀點(diǎn)是:我們不需要自己分析問(wèn)題,只需要拿社區(qū)的最新更新就行了。但是我們并不認(rèn)同,我們認(rèn)為技術(shù)團(tuán)隊(duì)自身的能力很重要,主要是如下原因:
      ?●??美團(tuán)的應(yīng)用規(guī)模大、場(chǎng)景復(fù)雜,很多問(wèn)題也許很多企業(yè)都沒(méi)有遇到過(guò),不能被動(dòng)的等別人來(lái)解答。
      ?●??對(duì)于一些實(shí)際的業(yè)務(wù)問(wèn)題或者需求(例如容器內(nèi)正確返回CPU數(shù)目),社區(qū)也許覺(jué)得不重要,或者不是正確的理念,可能就不會(huì)解決。
      ?●??社區(qū)很多時(shí)候只在Upstream解決問(wèn)題,而Upstream通常不穩(wěn)定,即使有Backport到我們正在使用的版本,排期也很難進(jìn)行保障。
      ?●??社區(qū)會(huì)發(fā)布很多補(bǔ)丁,通常描述都比較晦澀難懂,如果沒(méi)有對(duì)問(wèn)題的深刻理解,很難把遇到的實(shí)際問(wèn)題和一系列補(bǔ)丁聯(lián)系起來(lái)。
      ?●??對(duì)于一些復(fù)雜問(wèn)題,社區(qū)的解決方案不一定適用于我們自身的實(shí)際場(chǎng)景,我們需要自身有能力進(jìn)行判斷和取舍。

      性能


      容器平臺(tái)性能,主要包括兩個(gè)方面性能:
      ?●??業(yè)務(wù)服務(wù)運(yùn)行在容器上的性能。

      ?●??容器操作(創(chuàng)建、刪除等等)的性能。




      上圖是我們CPU分配的一個(gè)例子,我們采用的主流服務(wù)器是兩路24核服務(wù)器,包含兩個(gè)Node,每個(gè)12核,算上超線程共48顆邏輯CPU。屬于典型的NUMA(
      非一致訪存)架構(gòu):系統(tǒng)中每個(gè)Node有自己的內(nèi)存,Node內(nèi)的CPU訪問(wèn)自己的內(nèi)存的速度,比訪問(wèn)另一個(gè)Node內(nèi)存的速度快很多(差一倍左右)。


      過(guò)去我們?cè)?jīng)遇到過(guò)網(wǎng)絡(luò)中斷集中到CPU0上的問(wèn)題,在大流量下可能導(dǎo)致網(wǎng)絡(luò)延時(shí)增加甚至丟包。為保證網(wǎng)絡(luò)處理能力,我們從Node0上劃出了8顆邏輯CPU用來(lái)專門處理網(wǎng)絡(luò)中斷和宿主機(jī)系統(tǒng)上的任務(wù),例如鏡像解壓這類高CPU的工作,這8顆邏輯CPU不運(yùn)行任何容器的Workload。


      在容器調(diào)度方面,我們的容器CPU分配盡量不跨Node,實(shí)踐證明跨Node訪問(wèn)內(nèi)存對(duì)應(yīng)用性能的影響比較大。在一些計(jì)算密集型的場(chǎng)景下,容器分配在Node內(nèi)部會(huì)提升30%以上的吞吐量。當(dāng)然,按Node的分配方案也存在一定的弊端:會(huì)導(dǎo)致CPU的碎片增加,為了更高效地利用CPU資源,在實(shí)際系統(tǒng)中,我們會(huì)根據(jù)服務(wù)畫像的信息,分配一些對(duì)CPU不敏感的服務(wù)容器跨Node使用CPU資源。




      上圖是一個(gè)真實(shí)的服務(wù)在CPU分配優(yōu)化前后,響應(yīng)延時(shí)的TP指標(biāo)線對(duì)比。可以看到TP999線下降了一個(gè)數(shù)量級(jí),并且所有的指標(biāo)都更加平穩(wěn)。

      性能優(yōu)化:文件系統(tǒng)

      針對(duì)文件系統(tǒng)的性能優(yōu)化,第一步是選型,根據(jù)統(tǒng)計(jì)到的應(yīng)用讀寫特征,我們選擇了Ext4文件系統(tǒng)(超過(guò)85%的文件讀寫是對(duì)小于1M文件的操作)。

      Ext4文件系統(tǒng)有三種日志模式:
      ?●??Journal:寫數(shù)據(jù)前等待Metadata和數(shù)據(jù)的日志落盤。
      ?●??Ordered:只記錄Metadata的日志,寫Metadata日志前確保數(shù)據(jù)已經(jīng)落盤。
      ?●??Writeback:僅記錄Metadata日志,不保證數(shù)據(jù)比Metadata先落盤。

      我們選擇了Writeback模式(默認(rèn)是oderded
      ),它在幾種掛載模式中速度最快,缺點(diǎn)是:發(fā)生故障時(shí)數(shù)據(jù)不好恢復(fù)。我們大部分容器處于無(wú)狀態(tài),故障時(shí)在別的機(jī)器上再拉起一臺(tái)即可。因此我們?cè)谛阅芎头€(wěn)定性中,選擇了性能。容器內(nèi)部給應(yīng)用提供可選的基于內(nèi)存的文件系統(tǒng)tmpfs,可以提升有大量臨時(shí)文件讀寫的服務(wù)性能。




      如上圖所示,在美團(tuán)內(nèi)部創(chuàng)建一個(gè)虛擬機(jī)至少經(jīng)歷三步,平均時(shí)間超過(guò)300秒。使用鏡像創(chuàng)建容器平均時(shí)間23秒。容器的靈活、快速得到了顯著的體現(xiàn)。


      容器擴(kuò)容23秒的平均時(shí)間包含了各個(gè)部分的優(yōu)化,如擴(kuò)容鏈路優(yōu)化、鏡像分發(fā)優(yōu)化、初始化和業(yè)務(wù)拉起優(yōu)化等等。接下來(lái),本文主要介紹一下我們做的鏡像分發(fā)和解壓相關(guān)的優(yōu)化。




      上圖是美團(tuán)容器鏡像管理的總體架構(gòu),其特點(diǎn)如下:
      ?●??存在多個(gè)Site。
      ?●??支持跨Site的鏡像同步,根據(jù)鏡像的標(biāo)簽確定是否需要跨Site同步。
      ?●??每個(gè)Site有鏡像備份。
      ?●??每個(gè)Site內(nèi)部有實(shí)現(xiàn)鏡像分發(fā)的P2P網(wǎng)絡(luò)。

      鏡像分發(fā)是影響容器擴(kuò)容時(shí)長(zhǎng)的一個(gè)重要環(huán)節(jié)。



      ?●??跨Site同步:保證服務(wù)器總能從就近的鏡像倉(cāng)庫(kù)拉取到擴(kuò)容用的鏡像,減少拉取時(shí)間,降低跨Site帶寬消耗。
      ?●??
      基礎(chǔ)鏡像預(yù)分發(fā):美團(tuán)的基礎(chǔ)鏡像是構(gòu)建業(yè)務(wù)鏡像的公共鏡像,通常有幾百兆的大小。業(yè)務(wù)鏡像層是業(yè)務(wù)的應(yīng)用代碼,通常比基礎(chǔ)鏡像小很多。在容器擴(kuò)容的時(shí)候如果基礎(chǔ)鏡像已經(jīng)在本地,只需要拉取業(yè)務(wù)鏡像的部分,可以明顯地加快擴(kuò)容速度。為達(dá)到這樣的效果,我們會(huì)把基礎(chǔ)鏡像事先分發(fā)到所有的服務(wù)器上。
      ?●??
      P2P鏡像分發(fā):基礎(chǔ)鏡像預(yù)分發(fā)在有些場(chǎng)景會(huì)導(dǎo)致上千個(gè)服務(wù)器同時(shí)從鏡像倉(cāng)庫(kù)拉取鏡像,對(duì)鏡像倉(cāng)庫(kù)服務(wù)和帶寬帶來(lái)很大的壓力。因此我們開(kāi)發(fā)了鏡像P2P分發(fā)的功能,服務(wù)器不僅能從鏡像倉(cāng)庫(kù)中拉取鏡像,還能從其他服務(wù)器上獲取鏡像的分片。

      從上圖可以看出,隨著分發(fā)服務(wù)器數(shù)目的增加,原有分發(fā)時(shí)間也快速增加,而P2P鏡像分發(fā)時(shí)間基本上保持穩(wěn)定。




      Docker的鏡像拉取是一個(gè)并行下載,串行解壓的過(guò)程,為了提升解壓的速度,我們美團(tuán)也做了一些優(yōu)化工作。

      對(duì)于單個(gè)層的解壓,我們使用并行解壓算法替換Docker默認(rèn)的串行解壓算法,實(shí)現(xiàn)上是使用pgzip替換gzip。


      Docker的鏡像具有分層結(jié)構(gòu),對(duì)鏡像層的合并是一個(gè)“解壓一層合并一層,再解壓一層,再合并一層”的串行操作。實(shí)際上只有合并是需要串行的,解壓可以并行起來(lái)。我們把多層的解壓改成并行,解壓出的數(shù)據(jù)先放在臨時(shí)存儲(chǔ)空間,最后根據(jù)層之間的依賴進(jìn)行串行合并。
      前面的改動(dòng)(并行解壓所有的層到臨時(shí)空間)導(dǎo)致磁盤IO的次數(shù)增加了近一倍,也會(huì)導(dǎo)致解壓過(guò)程不夠快。


      于是,我們使用基于內(nèi)存的Ramdisk來(lái)存儲(chǔ)解壓出來(lái)的臨時(shí)文件,減輕了額外文件寫帶來(lái)的開(kāi)銷。做了上面這些工作以后,我們又發(fā)現(xiàn),容器的分層也會(huì)影響下載加解壓的時(shí)間。上圖是我們簡(jiǎn)單測(cè)試的結(jié)果:無(wú)論對(duì)于怎么分層的鏡像并行解壓,都能大幅提升解壓時(shí)間,對(duì)于層數(shù)多的鏡像提升更加明顯。

      推廣


      推廣容器的第一步是能說(shuō)出容器的優(yōu)勢(shì),我們認(rèn)為容器有如下優(yōu)勢(shì):
      ?●??輕量級(jí):容器小、快,能夠?qū)崿F(xiàn)秒級(jí)啟動(dòng)。
      ?●??應(yīng)用分發(fā):容器使用鏡像分發(fā),開(kāi)發(fā)測(cè)試容器和部署容器配置完全一致。
      ?●??彈性:可以根據(jù)CPU、內(nèi)存等資源使用或者QPS、延時(shí)等業(yè)務(wù)指標(biāo)快速擴(kuò)容容器,提升服務(wù)能力。

      這三個(gè)特性的組合,可以給業(yè)務(wù)帶來(lái)更大的靈活度和更低的計(jì)算成本。

      因?yàn)槿萜髌脚_(tái)本身是一個(gè)技術(shù)產(chǎn)品,它的客戶是各個(gè)業(yè)務(wù)的RD團(tuán)隊(duì),因此我們需要考慮下面一些因素:
      ?●??產(chǎn)品優(yōu)勢(shì):推廣容器平臺(tái)從某種程度上講,自身是一個(gè)ToB的業(yè)務(wù),首先要有好的產(chǎn)品,它相對(duì)于以前的解決方案(虛擬機(jī))存在很多優(yōu)勢(shì)。
      ?●??和已有系統(tǒng)打通:這個(gè)產(chǎn)品要能和客戶現(xiàn)有的系統(tǒng)很好的進(jìn)行集成,而不是讓客戶推翻所有的系統(tǒng)重新再來(lái)。
      ?●??原生應(yīng)用的開(kāi)發(fā)平臺(tái)、工具:這個(gè)產(chǎn)品要易于使用,要有配合工作的工具鏈。
      ?●??虛擬機(jī)到容器的平滑遷移:最好能提供從原有方案到新產(chǎn)品的遷移方案,并且容易實(shí)施。
      ?●??與應(yīng)用RD緊密配合:要提供良好的客戶支持,(即使有些問(wèn)題不是這個(gè)產(chǎn)品導(dǎo)致的也要積極幫忙解決)。
      ?●??資源傾斜:從戰(zhàn)略層面支持顛覆性新技術(shù):資源上向容器平臺(tái)傾斜,沒(méi)有足夠的理由,盡量不給配置虛擬機(jī)資源。
      總結(jié)


      Docker容器加Kubernetes編排是當(dāng)前容器云的主流實(shí)踐之一,美團(tuán)容器集群管理平臺(tái)HULK也采用了這樣的方案。本文主要分享了美團(tuán)在容器技術(shù)上做的一些探索和實(shí)踐。內(nèi)容主要涵蓋美團(tuán)容器云在Linux
      Kernel、Docker和Kubernetes層面做的一些優(yōu)化工作,以及美團(tuán)內(nèi)部推動(dòng)容器化進(jìn)程的一些思考,歡迎大家跟我們交流、探討。

      原文發(fā)布時(shí)間為:2018-11-29 本文作者:歐陽(yáng)堅(jiān) 本文來(lái)自云棲社區(qū)合作伙伴“數(shù)據(jù)和云
      <https://yq.aliyun.com/go/articleRenderRedirect?url=https%3A%2F%2Fmp.weixin.qq.com%2Fs%3F__biz%3DMjM5MDAxOTk2MQ%3D%3D%26amp%3Bmid%3D2650280227%26amp%3Bidx%3D1%26amp%3Bsn%3D2d9fb1f6d4f32ae47a8fb0919d9ff2b5%26amp%3Bchksm%3Dbe47893589300023512f2e314182cc231d547050d1ebc6ac46d53686334f4d71ca8dc2466404%26amp%3Bscene%3D0%23rd>
      ”,了解相關(guān)信息可以關(guān)注“數(shù)據(jù)和云
      <https://yq.aliyun.com/go/articleRenderRedirect?url=https%3A%2F%2Fmp.weixin.qq.com%2Fs%3F__biz%3DMjM5MDAxOTk2MQ%3D%3D%26amp%3Bmid%3D2650280227%26amp%3Bidx%3D1%26amp%3Bsn%3D2d9fb1f6d4f32ae47a8fb0919d9ff2b5%26amp%3Bchksm%3Dbe47893589300023512f2e314182cc231d547050d1ebc6ac46d53686334f4d71ca8dc2466404%26amp%3Bscene%3D0%23rd>
      ”。

      友情鏈接
      ioDraw流程圖
      API參考文檔
      OK工具箱
      云服務(wù)器優(yōu)惠
      阿里云優(yōu)惠券
      騰訊云優(yōu)惠券
      京東云優(yōu)惠券
      站點(diǎn)信息
      問(wèn)題反饋
      郵箱:[email protected]
      QQ群:637538335
      關(guān)注微信

        <ul id="qxxfc"><fieldset id="qxxfc"><tr id="qxxfc"></tr></fieldset></ul>
          亚洲黄片在线免费看 | 天堂色区 | 少妇一级婬片免费放 | 午夜国产福利 | 性生交大片免费看4 | 男女插插网站 | 国产在线观看免费麻豆 | 国产精品wwww | 久久久久国产精品老熟 | 亚洲无码高清一区 |