《騰訊Gaia平臺(tái)的Docker應(yīng)用實(shí)踐》要點(diǎn):
本文介紹了騰訊Gaia平臺(tái)的Docker應(yīng)用實(shí)踐,希望對(duì)您有用。如果有疑問,可以聯(lián)系我們。
本文由謝恒忠根據(jù)2016年1月24日@Container容器技術(shù)大會(huì)·北京站上陳純的演講《騰訊Gaia平臺(tái)的Docker應(yīng)用實(shí)踐》整理而成.
大家好,我是騰訊數(shù)據(jù)平臺(tái)部的陳純,今天非常高興為大家介紹一下騰訊Gaia平臺(tái)Docker實(shí)踐.
首先我介紹一下Gaia平臺(tái).Gaia平臺(tái)是騰訊數(shù)據(jù)平臺(tái)部資源調(diào)度和管理的系統(tǒng),承載公司的離線業(yè)務(wù)、實(shí)時(shí)業(yè)務(wù)以及在線設(shè)備service業(yè)務(wù),最大單集群達(dá)到8800臺(tái),并發(fā)資源池個(gè)數(shù)達(dá)到2000個(gè),服務(wù)于騰訊所有的事業(yè)群.
在2014年10月份我們正式上線對(duì)Docker類型的支持,通過Docker將Gaia云平臺(tái)以更好用的方式呈現(xiàn)給各個(gè)業(yè)務(wù).目前,Gaia平臺(tái)已經(jīng)服務(wù)于公司內(nèi)部游戲云、廣點(diǎn)通以及GPU深度學(xué)習(xí)等Docker類業(yè)務(wù).
下面我簡(jiǎn)要介紹一下Gaia架構(gòu).如下圖:
Gaia架構(gòu)
Gaia其實(shí)是我們基于Hadoop的YARN改造的一個(gè)Docker的調(diào)度系統(tǒng).
首先它相比社區(qū)的YARN有哪些特點(diǎn)呢?社區(qū)的YARN可能在RM、NM都已經(jīng)實(shí)現(xiàn)了無單點(diǎn)的設(shè)計(jì),可以熱升級(jí).在此基礎(chǔ)之上,我們自研了一個(gè)AM,負(fù)責(zé)所有Docker類作業(yè)的調(diào)度.然后我們對(duì)AM以及Docker也進(jìn)行了一定的改造,讓它支持無單點(diǎn)的一個(gè)設(shè)計(jì).右邊的圖中我們可以看到每個(gè)Slave節(jié)點(diǎn)上除了有NM之外,還有一個(gè)Docker進(jìn)程,負(fù)責(zé)拉起所有的Docker作業(yè),我們也實(shí)現(xiàn)了Docker的熱升級(jí).除了對(duì)Master節(jié)點(diǎn)進(jìn)行無單點(diǎn)改造之外,Gaia也為用戶的APP提供了本地重試和跨機(jī)重試兩種容災(zāi)方式.
第二點(diǎn)就是Gaia除了對(duì)CPU內(nèi)存以及網(wǎng)絡(luò)出帶寬進(jìn)行限制之外,還增加了對(duì)GPU和磁盤空間的隔離.
第三點(diǎn)是Gaia可以最大化的利用集群的所有資源,在保證用戶最低資源使用量的情況下,在集群有空閑資源時(shí)還能借集群的空閑資源進(jìn)行使用.
最后一點(diǎn)是我們自研的SFair調(diào)度器解決了調(diào)度器效率和擴(kuò)展性的,目前調(diào)度器每秒最多可調(diào)度4K個(gè)Container實(shí)例.
當(dāng)然我今天所演講的主要內(nèi)容并不是對(duì)Gaia進(jìn)行分析,我今天演講的內(nèi)容主要是跟Docker相關(guān)的,因?yàn)槲移匠T诮M里面也是負(fù)責(zé)Docker的研發(fā).
首先我們來看一下Docker Daemon單點(diǎn)問題,相信所有使用Docker的人都會(huì)遇到這個(gè)問題.Docker Daemon在退出時(shí)會(huì)殺掉所有的Container,這一點(diǎn)對(duì)于在線服務(wù)來說完全不可接受.
其次Docker的坑也比較多,比如我們用的1.6.×版本:
第一個(gè)問題是我們遇到了Docker stats.Docker stats其實(shí)是用來監(jiān)控Container實(shí)際使用資源的命令,當(dāng)你的Container拉起來之后,用Docker stats監(jiān)聽這個(gè)Container使用資源,當(dāng)Container被回收,Stop之后,Docker stats命令由于它沒有正確的回收內(nèi)存中的一些數(shù)據(jù)結(jié)構(gòu),會(huì)導(dǎo)致Docker Daemon crash,如果Docker Daemon crash,它就會(huì)把這個(gè)機(jī)器的所有Container都給殺掉.這個(gè)問題是我們遇到的,自己解決了,并且反饋到社區(qū)了.
第二個(gè)問題是Docker exec,Docker exec在Docker Daemon代碼里面沒有很好的做到同步,會(huì)引發(fā)一個(gè)NPE的異常,導(dǎo)致Docker Daemon crash.
第三個(gè)問題相信很多人都遇到過,在Docker 1.9.1版本之前,由于Container的stdout和stderr都會(huì)經(jīng)過Docker Daemon進(jìn)行緩存,并最終寫入到磁盤的一個(gè)文件中.當(dāng)Container打的日志量過大,或者速度過快,Docker Daemon來不及把這個(gè)日志寫到文件中的時(shí)候,就會(huì)導(dǎo)致Docker Daemon crash.
除了我這里列舉的一些Docker Daemon的bug會(huì)導(dǎo)致Docker Daemon crash之外,我們?nèi)粘R灿袑?duì)Docker Daemon進(jìn)行升級(jí)的一個(gè)需求.總而言之,Docker Daemon的單點(diǎn)問題是一個(gè)痛點(diǎn),所以我們就對(duì)Docker Daemon的熱升級(jí)功能進(jìn)行了開發(fā).要開發(fā)這樣一個(gè)功能,首先搞清楚Docker Daemon為什么會(huì)在它停止的時(shí)候殺掉所有的Container,主要是受限于兩點(diǎn):
第一用戶的進(jìn)程是Docker Daemon子進(jìn)程;
第二就是Container的IO流會(huì)經(jīng)過Daemon緩存,如果Docker Daemon掛掉的時(shí)候它不去殺掉所有的Container,在它被重新拉起來之后,它無法將這個(gè)IO流重新以原先的方式流經(jīng)Daemon,這樣勢(shì)必會(huì)對(duì)它的Docker attach造成影響,所以現(xiàn)在一直都沒有支持這樣一個(gè)無單點(diǎn)的設(shè)計(jì).
圖1
我們的做法也非常簡(jiǎn)單,就是把原先的兩層進(jìn)程父子關(guān)系變?yōu)槿龑?如圖1),在Docker Daemon代碼里面有一個(gè)monitor的組件,這個(gè)monitor的組件最開始是一個(gè)goroutine的方式,我們將這個(gè)goroutine的方式改為進(jìn)程的方式,等待Container的運(yùn)行結(jié)束.這樣在Docker Daemon掛掉的時(shí)候,它沒必要去殺掉Container,也沒必要去殺掉monitor,它只需要自己把自己的活干完退出之后,monitor的進(jìn)程它自己就會(huì)變成孤兒進(jìn)程,從而托管給INIT進(jìn)程,也就是進(jìn)程號(hào)唯一的進(jìn)程.這樣在Docker Daemon重啟之后,它就會(huì)從磁盤上加載所有Container的運(yùn)行狀態(tài),恢復(fù)所有的Container狀態(tài).
下面講述這樣做對(duì)上層的調(diào)度系統(tǒng)的影響.一般調(diào)度系統(tǒng)拉起一個(gè)Container之后會(huì)使用Docker wait的命令去等待這個(gè)Container的運(yùn)行結(jié)束,如果沒有熱升級(jí)功能的時(shí)候,client跟Daemon之間是通過http請(qǐng)求的方式通信的,那Docker Daemon掛掉之后勢(shì)必會(huì)給client返回一個(gè)connection reset的response,這樣的話上層的調(diào)度系統(tǒng)就勢(shì)必會(huì)受到一些影響,對(duì)于這個(gè)client的狀態(tài)就無法感知了.
圖 2
我們的做法就是(如圖2)將這個(gè)wait的請(qǐng)求轉(zhuǎn)發(fā)到monitor進(jìn)程,就是最開始還是client向Daemon請(qǐng)求說我要wait這個(gè)Container結(jié)束,那這個(gè)時(shí)候Docker Daemon發(fā)現(xiàn)自己已經(jīng)開啟熱升級(jí)功能的情況下,它將這個(gè)請(qǐng)求返回一個(gè)305 redirect
請(qǐng)求,把redirect請(qǐng)求返回給monitor,這時(shí)候客戶端收到這個(gè)response后,發(fā)現(xiàn)它是一個(gè)redirect ,它就會(huì)從location字段中拿到當(dāng)前要操作的這個(gè)container的monitor進(jìn)程的地址,是一個(gè)IP加端口的一個(gè)形式. client進(jìn)程就會(huì)給monitor進(jìn)程發(fā)送一個(gè)wait請(qǐng)求,這時(shí)候monitor進(jìn)程會(huì)等待container運(yùn)行結(jié)束,當(dāng)container運(yùn)行結(jié)束之后會(huì)給client端返回response.可以看到改成這樣一種工作流之后,DockerDaemon整個(gè)wait的請(qǐng)求過程跟Docker Daemon已經(jīng)沒有任何關(guān)系,它掛不掛其實(shí)對(duì)整個(gè)過程沒有任何的影響.
我接著介紹一下熱升級(jí)功能的實(shí)現(xiàn).首先為了兼容以前的方式,我們?cè)黾恿艘粋€(gè)開關(guān),就是hot restart參數(shù),并且將monitor的代碼組件進(jìn)行接口化設(shè)計(jì),讓它支持以前的goroutine以及外部進(jìn)程兩種方式.
其次由于Container結(jié)束時(shí)Docker Daemon可能是存活狀態(tài),也可能是已經(jīng)死掉的狀態(tài),所以monitor進(jìn)程在Container結(jié)束的時(shí)候會(huì)將它的啟動(dòng)和結(jié)束事件首先持久化到磁盤,再通知Docker Daemon更新Container狀態(tài).如果這時(shí)候Docker Daemon已經(jīng)掛掉了,我們就重啟一定的次數(shù),如果沒有通知成功,也不用繼續(xù)等待這個(gè)Daemon進(jìn)程啟動(dòng)就直接退出了,因?yàn)樗纫呀?jīng)把Container這個(gè)結(jié)束事件持久化到磁盤上了,當(dāng)Docker Daemon重啟之后,它就可以從磁盤加載這個(gè)Container的狀態(tài)遷移文件,從而可以正確的恢復(fù)Container的狀態(tài).
第三比如說為了解決wait以及attach這些命令的問題,我們就將這些請(qǐng)求重定向到monitor進(jìn)程進(jìn)行處理,比如說attach請(qǐng)求的IO流,它以前是通過Daemon進(jìn)行緩存的,那現(xiàn)在就通過monitor進(jìn)程進(jìn)行緩存,這樣Docker Daemon掛掉對(duì)于每個(gè)Container來說并沒有什么太大的影響.
第四比如說網(wǎng)絡(luò)狀態(tài),現(xiàn)在Container Daemon的網(wǎng)絡(luò)部分的代碼已經(jīng)全部遷出,遷出到一個(gè)新的工程叫做Libnetwork,Libnetwork中有很多的實(shí)體,比如說Libnetwork/Endpoint/Sandbox等有部分的狀態(tài)是保存在內(nèi)存中的,它原先自己會(huì)存儲(chǔ)一些global的網(wǎng)絡(luò)的狀態(tài),比如說global網(wǎng)絡(luò)指的是一些Overlay網(wǎng)絡(luò),這種網(wǎng)絡(luò),它需要一些全局信息的保存,所以它會(huì)存在global kv,global kv可能是zkEtcd或者是Consul ,我當(dāng)時(shí)在做這個(gè)功能的時(shí)候就為L(zhǎng)ibnetwork引入了localstore功能,這個(gè)功能就會(huì)存儲(chǔ)一些本地的網(wǎng)絡(luò)的狀態(tài)信息,比如說bridge模式的一些狀態(tài)信息.
相信使用Docker的人都會(huì)遇到網(wǎng)絡(luò)部分的問題,網(wǎng)絡(luò)部分是一個(gè)比較頭疼的問題,也是每一家都會(huì)必然解決的問題.原先Docker Daemon提供了兩種方式:
第一種是Host方式,是完全沒有隔離的一個(gè)方式,它的優(yōu)點(diǎn)是性能好,但是缺點(diǎn)也很明顯,就是沒有網(wǎng)絡(luò)隔離,有端口沖突的問題.
其次Docker Daemon提供了一個(gè)bridge方式,也就是NAT的網(wǎng)絡(luò)模式,這種網(wǎng)絡(luò)模式提供了網(wǎng)絡(luò)隔離的功能,它解決了端口沖突問題.但是Container IP是一個(gè)私有的IP,對(duì)外是不可見的.所以從另外一臺(tái)主機(jī)的Container想要直接訪問這個(gè)Container是不行的,必須得通過主機(jī)的一個(gè)映射之后的主機(jī)的一個(gè)IP,以及映射之后的端口去訪問這個(gè)Container.但是端口映射提高了業(yè)務(wù)遷移的成本,他們可能會(huì)需要去改代碼,或者去改配制.并且NAT的這種方式對(duì)網(wǎng)絡(luò)的IO性能比Host方式也低了接近10%.
看一下Gaia平臺(tái)在接入用戶業(yè)務(wù)的過程中遇到的一些網(wǎng)絡(luò)方面的需求.比如說用戶可能會(huì)覺得端口沖突問題它不想改代碼或者配置.第二就是可能有些業(yè)務(wù)會(huì)將本機(jī)的一個(gè)IP注冊(cè)到ZooKeeper上做服務(wù)發(fā)現(xiàn),這時(shí)候如果是使用NAT方式的話,這個(gè)私有IP如果注冊(cè)到ZooKeeper上是完全沒有任何意義的.第三就是有些業(yè)務(wù)會(huì)對(duì)有權(quán)限訪問自己服務(wù)的IP做限制,比如說做白名單限制,這時(shí)候在同一個(gè)主機(jī)上的Container互相訪問的時(shí)候,由于它的流量是從主機(jī)的Container首先發(fā)出,然后進(jìn)入到global space,這時(shí)候會(huì)對(duì)它的IP進(jìn)行原IP的替換,就是SNAT的過程.由于流量是從Docker 0進(jìn)入的,所以它會(huì)將原IP替換成Docker 0的IP,也就是一個(gè)私有的IP,這時(shí)候在同組機(jī)的另外一個(gè)Container中看到的原IP就不是這個(gè)主機(jī)的IP,它是Docker 0的原IP,很顯然這個(gè)IP是不能加入到它的白名單里面的,因?yàn)檫@是個(gè)私有IP,不能確定這個(gè)IP是從哪里訪問過來的.
我們當(dāng)初也做了一個(gè)改進(jìn),原先的SNAT的規(guī)則其實(shí)是MASQUERADE的規(guī)則,這個(gè)規(guī)則它會(huì)將原IP從哪個(gè)網(wǎng)卡進(jìn)就會(huì)替換成哪個(gè)網(wǎng)卡的一個(gè)IP,后來我們加了一條規(guī)則是將它的原IP寫死了,改成主機(jī)的IP,這樣它在另外一個(gè)Container看到的是主機(jī)的IP,所以就不會(huì)有問題.
下面一點(diǎn)就是很多業(yè)務(wù)使用騰訊的TGW網(wǎng)關(guān)對(duì)外提供服務(wù).我們?cè)跍y(cè)試TGW對(duì)接NAT方式的時(shí)候發(fā)現(xiàn)報(bào)文是不通的,之所以不通是因?yàn)橥饷娴牧髁吭L問進(jìn)來之后,它會(huì)首先做一個(gè)DNAT的過程,DNAT的過程會(huì)把目的IP轉(zhuǎn)化成Container的一個(gè)私有IP,之后當(dāng)Container中的進(jìn)程進(jìn)行回包的時(shí)候,這時(shí)候其實(shí)走的是一個(gè)NAT的過程,因?yàn)樗M(jìn)來的時(shí)候發(fā)生了DNAT的過程,這個(gè)過程是發(fā)生在PREROUTING階段,然后出去的時(shí)候是一個(gè)逆過程,這個(gè)時(shí)候這個(gè)包的IP的替換會(huì)發(fā)生在路由決策之后,這樣在路由決策的時(shí)候destination IP還沒有替換,所以導(dǎo)致這個(gè)TCP/IP的協(xié)議無法對(duì)包進(jìn)行封包,所以會(huì)導(dǎo)致通過TGW對(duì)接NAT的方式是不可行的.
下面一點(diǎn)是某些業(yè)務(wù),比如說GPU業(yè)務(wù),可能要求很好的網(wǎng)絡(luò)性能,這個(gè)也是通過NAT的方式無法解決的.
圖 3
下面就看我們對(duì)于網(wǎng)絡(luò)的改進(jìn)(如圖3).前面很多公司也介紹了,大家會(huì)給Container分配一個(gè)內(nèi)網(wǎng)IP,我們也是這么做的.但是我們所不同的是我們?cè)谠鹊木W(wǎng)橋上面加了一個(gè)VLAN設(shè)備,這個(gè)起到什么怎么呢?比如說有一些內(nèi)網(wǎng)IP跟主機(jī)的IP不處于同一個(gè)VLAN的時(shí)候,如果直接分配到Container中,通過網(wǎng)橋橋接起來,這時(shí)候網(wǎng)絡(luò)是不能通的,因?yàn)樾枰o它出的流量打上一個(gè)vlan tag它才能通,這樣我們就在原有的基礎(chǔ)之上加了一個(gè)VLAN設(shè)備,這個(gè)VLAN設(shè)備后面再橋接一個(gè)網(wǎng)橋,然后讓這些與主機(jī)的IP不同一個(gè)VLAN的IP的Container橋接到另外一個(gè)網(wǎng)橋上面, 這樣它出來都會(huì)打上這個(gè)vlan tag ,這樣就可以通了.這種方式相比NAT的方式,可能的IP對(duì)外可見,沒有端口映射帶來的遷移成本,也少了iptables或者是用戶態(tài)進(jìn)程的一個(gè)轉(zhuǎn)發(fā)過程,所以性能略優(yōu)于NAT的方式. 結(jié)合Gaia等上層調(diào)度系統(tǒng)可以實(shí)現(xiàn)IP漂移的功能,就是在Container發(fā)生遷移的過程中IP可以保持不變.
下面介紹一下SR-IOV技術(shù),SR-IOV技術(shù)是一個(gè)硬件虛擬化技術(shù),它可以由一個(gè)網(wǎng)卡虛擬出多個(gè)功能接口,每個(gè)功能接口實(shí)際上是可以做一個(gè)網(wǎng)卡使用的.通過這種硬件取代內(nèi)核的虛擬網(wǎng)絡(luò)設(shè)備的方式,可以極大的提高網(wǎng)絡(luò)的性能,并且減少了物理機(jī)CPU的消耗.Docker 1.9.0版本支持網(wǎng)絡(luò)插件的方式,所以我們實(shí)現(xiàn)了一個(gè)SR-IOV的網(wǎng)絡(luò)插件,去非常方便的使用這種方式.
下面(圖4)的一個(gè)圖表就是我們測(cè)試使用SR-IOV之后所帶來的性能的提升.橫坐標(biāo)是測(cè)試的主要是在虛擬化比是1:1和1:4的情況下,網(wǎng)絡(luò)流量包的大小是1個(gè)字節(jié)、64個(gè)字節(jié)和256個(gè)字節(jié)的情況下SR-IOV的方式相比NAT方式所帶來的包量的提升.
圖 4
第三就是Overlay網(wǎng)絡(luò)為我們提供了多租戶網(wǎng)絡(luò)隔離功能,并且每個(gè)租戶可以分配一個(gè)獨(dú)立的虛擬的IP段.這種方式不需要分配一個(gè)內(nèi)網(wǎng)的IP,也不需要依賴于NAT的方式,這種方式想必是以后必然會(huì)用上的一種多租戶的一個(gè)解決方案.但是Docker原生的Libnetwork在overlay driver為接入的Container默認(rèn)連接了一個(gè)NAT網(wǎng)絡(luò)對(duì)外提供服務(wù),通過這個(gè)NAT的網(wǎng)絡(luò)Container就不單可以訪問與自己位于一個(gè)Overlay的其它的Container,也可以訪問外網(wǎng),因?yàn)樗峭ㄟ^NAT的方式去訪問的.但是很多Container并不一定需要訪問內(nèi)網(wǎng)或者外網(wǎng),所以我們給Libnetwork對(duì)象增加了一個(gè)internal開關(guān),創(chuàng)建完全與外界隔離的一個(gè)網(wǎng)絡(luò).
圖 5
這個(gè)圖(圖5 )是位于不同主機(jī)上的5個(gè)Container,C1和C2構(gòu)成一個(gè)Overlay網(wǎng)絡(luò),C3、C4、C5構(gòu)成另外一個(gè)Overlay網(wǎng)絡(luò),這兩個(gè)網(wǎng)絡(luò)彼此之間不同,如果說某些Container想要對(duì)外提供服務(wù),這時(shí)候我們可以給它分配一個(gè)內(nèi)網(wǎng)的IP,讓它對(duì)外提供服務(wù).
接下來分享一下我們?cè)诖鎯?chǔ)方面的工作.Container數(shù)據(jù)存儲(chǔ)相信也是使用Docker的人繞不開的一個(gè)問題.我們的做法就是在Container遷移后不需要保留的數(shù)據(jù),就給它分配一個(gè)host volume進(jìn)行存儲(chǔ)它的數(shù)據(jù).如果這個(gè)Container遷移之后它的數(shù)據(jù)需要保留,給它分配一個(gè)Ceph RBD存儲(chǔ),我們是使用了Ceph volume plugin為每個(gè)Container分配一個(gè)RBD的存儲(chǔ)目錄.
接下來介紹一下我們?cè)谫Y源隔離方面的一些工作.Docker本身對(duì)內(nèi)存的控制是hard limit方式,就是Container的進(jìn)程的內(nèi)存如果超過它申請(qǐng)的,比如說5G的一個(gè)總的上限,它就會(huì)將這個(gè)Container給殺掉.但是這種方式就非常不方便,比如說用戶可能并不知道它的Container實(shí)際到峰值的時(shí)候使用到多少的內(nèi)存,并且在很多情況下當(dāng)Container超過它的內(nèi)存上限的時(shí)候,這個(gè)機(jī)器的所有內(nèi)存其實(shí)還有很多的空閑,這時(shí)候我們的做法是為這個(gè)機(jī)器上所有的Container設(shè)置一個(gè)總的流程上限,Hard limit.單個(gè)Container內(nèi)存使用超出申請(qǐng)值,如果這個(gè)機(jī)器的所有Container沒有超出設(shè)置的總的Hard limit值時(shí)不會(huì)觸發(fā)kill,只有當(dāng)總的內(nèi)存超過Hard limit一定的百分比之后,才kill那些超出內(nèi)存申請(qǐng)值最多的Container,這種方式可以大大降低集群中Container被kill的幾率.
下面一點(diǎn)是我們?cè)谧鼍W(wǎng)絡(luò)出帶寬的控制的時(shí)候發(fā)現(xiàn),如果直接使用net_cls的方式對(duì)流量進(jìn)行標(biāo)志的時(shí)候,數(shù)據(jù)包會(huì)經(jīng)過bridge之后pid會(huì)發(fā)生丟失,這時(shí)候打的標(biāo)記是沒有效果的.所以我們的做法就是在iptables的mangle表中對(duì)Container出流量按IP進(jìn)行標(biāo)記,這個(gè)時(shí)候我們就可以方便的使用TC工具對(duì)標(biāo)記的流量進(jìn)行限制.
下面一個(gè)問題也是很多講師都講到的問題,是容器中自然顯示的問題,原先跑在物理機(jī)或者虛擬機(jī)中的業(yè)務(wù)在使用騰訊網(wǎng)管系統(tǒng)記錄機(jī)器的資源使用情況,但是如果都遷移到Container中之后,這個(gè)時(shí)候Container中顯示的資源可能是主機(jī)的資源,那并不是它自己實(shí)際使用的資源.所以我們就需要解決這個(gè)問題,可能有一些團(tuán)隊(duì)是通過修改內(nèi)核的方式去解決的,但是修改內(nèi)核可能還需要自己維護(hù)這些patch.我們的做法就是通過FUSE實(shí)現(xiàn)了一個(gè)用戶態(tài)的文件系統(tǒng),這個(gè)用戶態(tài)的文件系統(tǒng)使用的是Cgroup的數(shù)據(jù)統(tǒng)計(jì)Container的實(shí)際資源使用,它可以為每個(gè)Container生成仿真的meminfo stats或者diskstats cpuuinfo文件,然后在啟動(dòng)Container的時(shí)候?qū)⑦@些文件直接mount到Container中,這個(gè)程序是用go語言實(shí)現(xiàn)的,使得它非常方便的嵌入到Docker的代碼中,整個(gè)過程對(duì)Docker用戶透明,這個(gè)鏈接(?https://github.com/chenchun/cgroupfs)是我們做的這個(gè)功能的代碼的地址.
文:陳純
文章出處:Docker
轉(zhuǎn)載請(qǐng)注明本頁網(wǎng)址:
http://www.fzlkiss.com/jiaocheng/4470.html