從事容器方面工作的朋友可能已經(jīng)聽說過DC/OS,往往大家誤解DC/OS就是marathon + mesos,其實(shí)DC/OS包含很多的組件,這里給大家做一個(gè)介紹。
一、DC/OS的基本思想
所謂的DC/OS,全稱為數(shù)據(jù)中心操作系統(tǒng),其基本的思想就是使得運(yùn)維人員操作整個(gè)數(shù)據(jù)中如操作一臺(tái)電腦一樣。
DC/OS使用了哪些技術(shù)可以做到這一點(diǎn)呢?
請(qǐng)點(diǎn)擊此處輸入圖片描述
如圖,左面是普通的Linux操作系統(tǒng),右面是DC/OS,在這里做了一個(gè)對(duì)比。
無論是哪種操作系統(tǒng),都需要管理外部的硬件設(shè)備,最重要的四種硬件資源即CPU,內(nèi)存,存儲(chǔ),網(wǎng)絡(luò)。
最初使用匯編語言寫程序的前輩,還是需要指定使用那些硬件資源的,例如指定使用哪個(gè)寄存器,放在內(nèi)存的哪個(gè)位置,寫入或者讀取那個(gè)串口等,對(duì)于這些資源的使用,需要程序員自己心里非常的清楚,要不然一旦JUMP錯(cuò)了位置,程序就無法運(yùn)行。這就像運(yùn)維數(shù)據(jù)中心的一臺(tái)臺(tái)物理機(jī)的前輩一樣,那個(gè)程序放在了哪臺(tái)機(jī)器上,使用多少內(nèi)存,多少硬盤,都需要心里非常的清楚。
為了將程序員從對(duì)硬件的直接操作中解放出來,提升程序設(shè)計(jì)的效率,從而有了操作系統(tǒng)這一層,實(shí)現(xiàn)對(duì)于硬件資源的統(tǒng)一管理。某個(gè)程序使用哪個(gè)CPU,哪部分內(nèi)存,哪部分硬盤,程序只需要調(diào)用API就可以了,由操作系統(tǒng)自行分配和管理,其實(shí)操作系統(tǒng)只做了一件事情,就是調(diào)度。對(duì)應(yīng)到數(shù)據(jù)中心,也需要一個(gè)調(diào)度器,將運(yùn)維人員從指定物理機(jī)或者虛擬機(jī)的痛苦中解放出來,這就是Mesos。Mesos即使數(shù)據(jù)中心操作系統(tǒng)的內(nèi)核。
在使用操作系統(tǒng)的時(shí)候,我們可以開發(fā)驅(qū)動(dòng)程序來識(shí)別新的硬件資源,可以開發(fā)內(nèi)核模塊(例如openvswitch.ko)來干預(yù)對(duì)于硬件資源的使用,對(duì)于Mesos,同樣可以開發(fā)isolator來識(shí)別新的硬件資源例如GPU,也可以開發(fā)Executor來干預(yù)資源的使用。
在內(nèi)核之上,就是系統(tǒng)服務(wù),例如systemd,是用來維護(hù)進(jìn)程運(yùn)行的,如果systemctl enable xxx,則保證服務(wù)掛掉后自動(dòng)重啟。對(duì)于DC/OS,保持服務(wù)long run的是marathon,但是僅僅只有marathon還不夠,因?yàn)榉?wù)是啟動(dòng)在多臺(tái)機(jī)器上的,而且服務(wù)之間是有依賴關(guān)系的,一個(gè)服務(wù)掛掉了,在另外一臺(tái)機(jī)器啟動(dòng)起來,如何保持服務(wù)之間的調(diào)用不需要人工干預(yù)呢?這需要另外的技術(shù),稱為服務(wù)發(fā)現(xiàn),多是通過DNS,負(fù)載均衡,虛擬機(jī)IP等技術(shù)實(shí)現(xiàn)的。
使用操作系統(tǒng),需要安裝一些軟件,于是需要yum之類的包管理系統(tǒng),使得軟件的使用者和軟件的編譯者分隔開來,軟件的編譯者需要知道這個(gè)軟件需要安裝哪些包,包之間的依賴關(guān)系是什么,軟件安裝到什么地方,而軟件的使用者僅僅需要yum install就可以了。DC/OS就有這樣一套包管理軟件,和其他的容器管理平臺(tái)需要自己編譯Docker鏡像,自己寫yml,自己管理依賴不同,DC/OS的軟件使用者只需要dcos package install就可以安裝好軟件了,軟件的配置,節(jié)點(diǎn)數(shù)目,依賴關(guān)系都是有軟件編譯者設(shè)置。
在最外層,DC/OS像普通的操作系統(tǒng)一樣,有統(tǒng)一的界面和命令行。通過它們,可以管理安裝包,管理節(jié)點(diǎn),運(yùn)行任務(wù)等。DC/OS不僅僅是運(yùn)行容器的平臺(tái),如果僅僅運(yùn)行容器,就是容器管理平臺(tái),而非數(shù)據(jù)中心操作系統(tǒng)。通過DC/OS,你可以在每臺(tái)機(jī)器上運(yùn)行一個(gè)命令來進(jìn)行統(tǒng)一的配置,而無需登錄到每臺(tái)機(jī)器上去。你可以運(yùn)行容器應(yīng)用和大數(shù)據(jù)分析應(yīng)用并共享資源,并且可以相互發(fā)現(xiàn),這更加符合現(xiàn)代互聯(lián)網(wǎng)應(yīng)用,微服務(wù)和大數(shù)據(jù)不可分割。而且Mesos的架構(gòu)非常開放,你可以通過開發(fā)Framework, Executor, Modules, Hooks等,輕松干預(yù)微服務(wù)或者大數(shù)據(jù)任務(wù)的執(zhí)行過程,來定制化你的應(yīng)用。這也符合操作系統(tǒng)微內(nèi)核的概念。
二、DC/OS的內(nèi)核模塊Mesos
Mesos架構(gòu)如下
請(qǐng)點(diǎn)擊此處輸入圖片描述
這個(gè)圖比較的著名了,也有很多文章介紹這個(gè)圖,詳情可以看文章http://mesos.apache.org/documentation/latest/architecture/,這里不做過多的介紹。
從圖中可以看到,Mesos有Framework(Framework里面有Scheduler), Master(Master里面有allocator), Agent, Executor, Task幾部分組成。這里面有兩層的Scheduler,一層在Master里面,allocator會(huì)將資源公平的分給每一個(gè)Framework,二層在Framework里面,F(xiàn)ramework的scheduler將資源按規(guī)則分配給Task。
Mesos的這幾個(gè)角色在一個(gè)任務(wù)運(yùn)行的生命周期中,相互關(guān)系如下:
請(qǐng)點(diǎn)擊此處輸入圖片描述
Agent會(huì)將資源匯報(bào)給Master,Master會(huì)根據(jù)allocator的策略將資源offer給framework的scheduler。Scheduler 可以accept這個(gè)資源,運(yùn)行一個(gè)Task,Master將Task交給Agent,Agent交給Executor去真正的運(yùn)行這個(gè)Task。
這個(gè)圖相對(duì)比較的簡(jiǎn)略,真正詳細(xì)的過程比這個(gè)復(fù)雜很多,大家可以參考這篇博客http://www.cnblogs.com/popsuper1982/p/5926724.html,在代碼級(jí)別分析了整個(gè)任務(wù)運(yùn)行的過程,還畫了一個(gè)泳道圖http://images2015.cnblogs.com/blog/635909/201608/635909-20160806163718778-1628977219.png。
要研究Mesos,熟悉整個(gè)過程非常重要,這樣一個(gè)任務(wù)運(yùn)行出現(xiàn)問題的時(shí)候,才能比較好的定位問題在哪里,如果解決。Mesos將一個(gè)簡(jiǎn)單的任務(wù)的運(yùn)行過程,分成如此多的層次,如此多的角色來做,是為了雙層調(diào)度和靈活配置,這是一個(gè)內(nèi)核應(yīng)該做的事情。
我們?nèi)绾胃深A(yù)一個(gè)Task的運(yùn)行過程呢?
第一、寫一個(gè)Framework
如果你想完全自己控制Task的運(yùn)行,而非讓Marathon來運(yùn)行并保持一個(gè)無狀態(tài)的Task長(zhǎng)運(yùn)行,就需要自己寫一個(gè)Framework,在你的Framework里面,三個(gè)Task之間的關(guān)系你可以自己定義,而非像Marathon一樣,Task * 3,3個(gè)任務(wù)不分彼此,你的Framework可以控制這三個(gè)Task一主兩備,可以控制三個(gè)Task的啟動(dòng)順序,可以將一個(gè)先啟動(dòng)的Task的IP,位置等通過環(huán)境變量告知另外兩個(gè)Task。
寫一個(gè)Framework需要寫一個(gè)Scheduler,實(shí)現(xiàn)一些接口,如文檔http://mesos.apache.org/documentation/latest/app-framework-development-guide/中所述。
然后使用使用MesosSchedulerDriver來運(yùn)行這個(gè)Scheduler。
請(qǐng)點(diǎn)擊此處輸入圖片描述
其實(shí)Mesos這些模塊之間的通信都是通過Protocol Buffer定義消息來交互的,然而如果讓Framework的開發(fā)人員還要學(xué)會(huì)如何使用Protocol Buffer消息和Mesos Master通信,是很痛苦的事情,所以MesosSchedulerDriver幫助你做了這個(gè)事情,你只需要實(shí)現(xiàn)Scheduler定義的接口就可以了,不需要了解這些接口是誰調(diào)用的,調(diào)用了接口之后,消息如何傳給Mesos Master。
所有的接口里面,最重要的是resourceOffers函數(shù),根據(jù)得到的offers(每個(gè)slave都有多少資源),創(chuàng)建一系列tasks,然后調(diào)用MesosSchedulerDriver的launchTasks函數(shù),MesosSchedulerDriver會(huì)將這些tasks封裝為L(zhǎng)aunchTasksMessage發(fā)送給Mesos Master。
第二、寫一個(gè)Allocator
通過上面的描述,Mesos有兩層調(diào)度,第一層就是Allocator,將資源分配給Framework。
Mesos允許用戶通過自己寫Module的方式,寫一個(gè)so,然后啟動(dòng)的時(shí)候加載進(jìn)去,然后在命令行里面指定使用so中的哪個(gè)Module。
當(dāng)然寫Allocator的不多,因?yàn)镸esos的DRF算法是Mesos的核心,如果不用這個(gè)算法,還不如不用mesos。
Mesos源碼中默認(rèn)的Allocator,即HierarchicalDRFAllocator的位置在$MESOS_HOME/src/master/allocator/mesos/hierarchical.hpp,而DRF中對(duì)每個(gè)Framework排序的Sorter位于$MESOS_HOME/src/master/allocator/sorter/drf/sorter.cpp,可以查看其源碼了解它的工作原理。
HierarchicalDRF的基本原理
如何作出offer分配的決定是由資源分配模塊Allocator實(shí)現(xiàn)的,該模塊存在于Master之中。資源分配模塊確定Framework接受offer的順序,與此同時(shí),確保在資源利用最大化的條件下公平地共享資源。
由于Mesos為跨數(shù)據(jù)中心調(diào)度資源并且是異構(gòu)的資源需求時(shí),資源分配相比普通調(diào)度將會(huì)更加困難。因此Mesos采用了DRF(主導(dǎo)資源公平算法 Dominant Resource Fairness)
Framework擁有的全部資源類型份額中占最高百分比的就是Framework的主導(dǎo)份額。DRF算法會(huì)使用所有已注冊(cè)的Framework來計(jì)算主導(dǎo)份額,以確保每個(gè)Framework能接收到其主導(dǎo)資源的公平份額。
舉個(gè)例子
考慮一個(gè)9CPU,18GBRAM的系統(tǒng),擁有兩個(gè)用戶,其中用戶A運(yùn)行的任務(wù)的需求向量為{1CPU, 4GB},用戶B運(yùn)行的任務(wù)的需求向量為{3CPU,1GB},用戶可以執(zhí)行盡量多的任務(wù)來使用系統(tǒng)的資源。
在上述方案中,A的每個(gè)任務(wù)消耗總cpu的1/9和總內(nèi)存的2/9,所以A的dominant resource是內(nèi)存;B的每個(gè)任務(wù)消耗總cpu的1/3和總內(nèi)存的1/18,所以B的dominant resource為CPU。DRF會(huì)均衡用戶的dominant shares,執(zhí)行3個(gè)用戶A的任務(wù),執(zhí)行2個(gè)用戶B的任務(wù)。三個(gè)用戶A的任務(wù)總共消耗了{(lán)3CPU,12GB},兩個(gè)用戶B的任務(wù)總共消耗了{(lán)6CPU,2GB};在這個(gè)分配中,每一個(gè)用戶的dominant share是相等的,用戶A獲得了2/3的RAM,而用戶B獲得了2/3的CPU。
以上的這個(gè)分配可以用如下方式計(jì)算出來:x和y分別是用戶A和用戶B的分配任務(wù)的數(shù)目,那么用戶A消耗了{(lán)xCPU,4xGB},用戶B消耗了{(lán)3yCPU,yGB},在圖三中用戶A和用戶B消耗了同等dominant resource;用戶A的dominant share為4x/18,用戶B的dominant share為3y/9。所以DRF分配可以通過求解以下的優(yōu)化問題來得到:
max(x,y) #(Maximize allocations)
subject to
x + 3y <= 9 #(CPU constraint)
4x + y <= 18 #(Memory Constraint)
2x/9 = y/3 #(Equalize dominant shares)
最后解出x=3以及y=2,因而用戶A獲得{3CPU,12GB},B得到{6CPU, 2GB}。
HierarchicalDRF核心算法實(shí)現(xiàn)在Src/main/allocator/mesos/hierarchical.cpp中HierarchicalAllocatorProcess::allocate函數(shù)中。
概況來說調(diào)用了三個(gè)Sorter(quotaRoleSorter, roleSorter, frameworkSorter),對(duì)所有的Framework進(jìn)行排序,哪個(gè)先得到資源,哪個(gè)后得到資源。
總的來說分兩大步:先保證有quota的role,調(diào)用quotaRoleSorter,然后其他的資源沒有quota的再分,調(diào)用roleSorter。
對(duì)于每一個(gè)大步分兩個(gè)層次排序:一層是按照role排序,第二層是相同的role的不同F(xiàn)ramework排序,調(diào)用frameworkSorter。
每一層的排序都是按照計(jì)算的share進(jìn)行排序來先給誰,再給誰。
這里有幾個(gè)概念容易混淆:Quota, Reservation, Role, Weight
每個(gè)Framework可以有Role,既用于權(quán)限,也用于資源分配
可以給某個(gè)role在offerResources的時(shí)候回復(fù)Offer::Operation::RESERVE,來預(yù)訂某臺(tái)slave上面的資源。Reservation是很具體的,具體到哪臺(tái)機(jī)器的多少資源屬于哪個(gè)Role
Quota是每個(gè)Role的最小保證量,但是不具體到某個(gè)節(jié)點(diǎn),而是在整個(gè)集群中保證有這么多就行了。
Reserved資源也算在Quota里面。
不同的Role之間可以有Weight
在allocator算法結(jié)束之后,便調(diào)用Master::Offer,最終調(diào)用Framework的Scheduler的resourceOffers,讓Framework進(jìn)行二次調(diào)度。同上面的邏輯就串聯(lián)起來。
第三、寫一個(gè)Hook
你可以寫hook模塊,講代碼插在很多關(guān)鍵的步驟,從而改寫整個(gè)Executor或者Docker或者Task的啟動(dòng)的整個(gè)過程。
可以干預(yù)的hook的地方定義在mesos/hook.hpp中。
Class hook定義如下:
請(qǐng)點(diǎn)擊此處輸入圖片描述
其中比較常用的是slavePrelaunchDockerHook,可以在Docker啟動(dòng)之前做一些事情,比如準(zhǔn)備工作。
還有slaveRemoveExecutorHook,這個(gè)可以在executor結(jié)束的時(shí)候,做一些事情,比如清理工作。
第四、創(chuàng)建Isolator
當(dāng)你有一種新的資源需要管理,并且每個(gè)Task需要針對(duì)這個(gè)資源進(jìn)行隔離的時(shí)候,寫一個(gè)Isolator就是有必要的了。
例如默認(rèn)的容器并不能動(dòng)態(tài)指定并限制任務(wù)硬盤使用的大小,所以mesos-containerizer就有了"disk/du"來定時(shí)查看任務(wù)使用的硬盤大小,當(dāng)超出限制的時(shí)候采取操作。
Src/slave/containerizer/mesos/containerizer.cpp里面列出了當(dāng)前支持的isolator,你也可以實(shí)現(xiàn)自己的isolator,并且通過modules參數(shù)load進(jìn)去。
Isolator定義了以下函數(shù)
請(qǐng)點(diǎn)擊此處輸入圖片描述
在運(yùn)行一個(gè)容器的最后,會(huì)調(diào)用每一個(gè)isolator的isolate函數(shù),通過這個(gè)函數(shù),可以對(duì)資源進(jìn)行一定的限制,例如寫入cgroup文件等,但是對(duì)于硬盤使用量,其實(shí)沒有cgroup可以設(shè)置,需要過一段時(shí)間du一些,這就需要實(shí)現(xiàn)watch函數(shù),過一段時(shí)間查看一下硬盤使用量,超過后做一定的操作。
第五、寫一個(gè)Executor
如果運(yùn)行一個(gè)普通的容器,或者命令行,則不需要實(shí)現(xiàn)Executor,僅僅Mesos默認(rèn)的Executor就能夠?qū)崿F(xiàn)這個(gè)功能。如果你需要在Executor里面做很多自己定制化的工作,則需要自己寫Executor。
寫一個(gè)Executor需要實(shí)現(xiàn)一些接口,最重要的就是launchTask接口,然后MesosExecutorDriver將這個(gè)Executor運(yùn)行起來。
就像Framework一樣,Executor也是通過protocol buffer協(xié)議和Mesos-Agent進(jìn)行溝通,通過MesosExecutorDriver,你不需要關(guān)心協(xié)議的事情,僅僅需要實(shí)現(xiàn)接口即可。
三、DC/OS的核心模塊
下面的圖描述了DC/OS的部署架構(gòu)圖:
請(qǐng)點(diǎn)擊此處輸入圖片描述
在DC/OS看來,所有的節(jié)點(diǎn)分為三個(gè)區(qū)域,一個(gè)是管理區(qū)域,主要處理對(duì)于服務(wù)的管理方面的操作,如增刪查改,啟停擴(kuò)縮等。為了高可用,Master節(jié)點(diǎn)可以是多個(gè),在多個(gè)Master節(jié)點(diǎn)之前,需要有一個(gè)負(fù)載均衡器。第二個(gè)是對(duì)外服務(wù)區(qū)域,也即外界能夠訪問DC/OS內(nèi)部的服務(wù)的區(qū)域,這個(gè)區(qū)域里面的服務(wù)多為對(duì)外的Nginx之類的,也會(huì)有marathon-lb來做外部的負(fù)載均衡器,所有對(duì)外服務(wù)區(qū)域的節(jié)點(diǎn)之外還需要一個(gè)負(fù)載均衡器。第三個(gè)區(qū)域是內(nèi)部服務(wù)區(qū)域,用于部署內(nèi)部服務(wù),如數(shù)據(jù)庫(kù),消息總線等,這些內(nèi)部節(jié)點(diǎn)不能對(duì)外訪問。
第一、Admin Router
AdminRouter是一個(gè)反向代理,正是它將對(duì)外的區(qū)域和對(duì)內(nèi)的區(qū)域完全隔離開來,在admin router之外,可以通過公網(wǎng)訪問,在admin router之內(nèi)全部是私網(wǎng)地址,這樣提供了安全的統(tǒng)一訪問機(jī)制。
安裝完畢Open DC/OS之后,安裝一個(gè)dcos的命令行工具,通過這個(gè)工具可以ssh到master的節(jié)點(diǎn)上。
eval `ssh-agent -s`
ssh-add .ssh/aws01.pem
dcos node ssh --master-proxy --leader
在這個(gè)節(jié)點(diǎn)上/etc/systemd/system路徑下面有三個(gè)systemd的service,Open DC/OS的所有組件都是用systemd進(jìn)行管理的。
ip-10-0-7-1 system # ls -l | grep adminrouter
lrwxrwxrwx. 1 root root 135 Oct 3 08:00 dcos-adminrouter-reload.service -> /opt/mesosphere/packages/adminrouter--cee9a2abb16c28d1ca6c74af1aff6bc4aac3f134/dcos.target.wants_master/dcos-adminrouter-reload.service
lrwxrwxrwx. 1 root root 133 Oct 3 08:00 dcos-adminrouter-reload.timer -> /opt/mesosphere/packages/adminrouter--cee9a2abb16c28d1ca6c74af1aff6bc4aac3f134/dcos.target.wants_master/dcos-adminrouter-reload.timer
lrwxrwxrwx. 1 root root 128 Oct 3 08:00 dcos-adminrouter.service -> /opt/mesosphere/packages/adminrouter--cee9a2abb16c28d1ca6c74af1aff6bc4aac3f134/dcos.target.wants_master/dcos-adminrouter.service
可以看到dcos-adminrouter.service是指向/opt/mesosphere/packages下面的一個(gè)路徑,Open DC/OS的所有組件都是安裝在這個(gè)路徑下面的。
在/opt/mesosphere/packages/adminrouter--cee9a2abb16c28d1ca6c74af1aff6bc4aac3f134/nginx/conf這個(gè)路徑下面,有一個(gè)文件nginx.master.conf,打開這個(gè)文件,就能看到熟悉的對(duì)于nginx的配置。
upstream mesos {
????server leader.mesos:5050;
}
upstream marathon {
????server master.mesos:8080;
}
location /mesos/ {
????access_by_lua 'auth.validate_jwt_or_exit()';
????proxy_set_header Host $http_host;
????proxy_pass http://mesos/;
}
location /marathon/ {
????# Enforce access restriction. Auth-wise, treat /marathon*
????# equivalently to /service/marathon*.
????access_by_lua 'auth.validate_jwt_or_exit()';
????proxy_set_header Host $http_host;
????proxy_pass http://marathon/;
}
從這個(gè)配置文件可以看出,所有對(duì)內(nèi)的訪問marathon的頁面,訪問mesos的頁面,都是通過leader.mesos進(jìn)行,這個(gè)域名是mesos-dns給出的,對(duì)應(yīng)的是內(nèi)部的IP地址,如果從外部訪問marathon或者mesos的頁面,則必須通過admin router,通過http://admin-router-external-ip/marathon或者h(yuǎn)ttp://admin-router-external-ip/mesos來訪問。
第二、Mesos-DNS
對(duì)于數(shù)據(jù)中心操作系統(tǒng)來講,服務(wù)發(fā)現(xiàn)和負(fù)載均衡是最最核心的功能,只有有了這些功能,才能使得服務(wù)的物理布局,服務(wù)之間的依賴關(guān)系,服務(wù)掛掉之后的自動(dòng)修復(fù)不需要用戶關(guān)心,才能使得用戶像用一臺(tái)電腦一樣使用整個(gè)數(shù)據(jù)中心。
如果服務(wù)之間的相互調(diào)用不使用IP地址,而使用域名的話,問題會(huì)簡(jiǎn)單很多。
請(qǐng)點(diǎn)擊此處輸入圖片描述
如圖所示,對(duì)于Mesos上運(yùn)行的每一個(gè)Task,Mesos-DNS都可以通過調(diào)用Mesos-Master的API得到,并且為每個(gè)Task分配一個(gè)域名和IP的對(duì)應(yīng)項(xiàng)。如果一個(gè)Task需要訪問另一個(gè)Task,則需要配置域名即可,無論Task如何掛掉,如何分配到其他的節(jié)點(diǎn)上運(yùn)行,域名都不會(huì)變,當(dāng)然Task的IP可能會(huì)變,但是不用擔(dān)心,Mesos-DNS會(huì)更新它。每個(gè)Mesos-Agent只需要配置/etc/resolv.conf指向mesos-dns就可以了。
當(dāng)一個(gè)Task運(yùn)行的時(shí)候,Mesos-DNS會(huì)創(chuàng)建一個(gè)域名..mesos對(duì)應(yīng):
Mesos-Agent的IP地址
如果是Mesos Containerizer的話,返回的是Task內(nèi)部容器的IP
另外..slave.mesos還會(huì)提供所在的物理機(jī)的IP地址。這樣通過hostport和Mesos-DNS所給的域名,可以實(shí)現(xiàn)服務(wù)的發(fā)現(xiàn)。
第三:marathon-lb
使用DNS雖然可以實(shí)現(xiàn)服務(wù)的自發(fā)現(xiàn),但是不容易實(shí)現(xiàn)服務(wù)的負(fù)載均衡和彈性伸縮,而marathon-lb實(shí)現(xiàn)了這些功能。
請(qǐng)點(diǎn)擊此處輸入圖片描述
Marathon-lb是一個(gè)基于haproxy的負(fù)載均衡器,但是它會(huì)監(jiān)聽marathon event bus,每當(dāng)注冊(cè)到marathon-lb上的服務(wù)數(shù)目變化的時(shí)候,marathon-lb也會(huì)自動(dòng)更新haproxy的配置文件,從而實(shí)現(xiàn)負(fù)載均衡。Marathon-lb可以如圖中實(shí)現(xiàn)對(duì)外的負(fù)載均衡,也可以實(shí)現(xiàn)對(duì)內(nèi)的服務(wù)之間相互調(diào)用的負(fù)載均衡。
Marathon的安裝可以在界面中universe里面搜索marathon-lb安裝,也可以通過命令行執(zhí)行dcos package install Marathon-LB進(jìn)行安裝,默認(rèn)安裝的對(duì)外的負(fù)載均衡器。
我們?cè)诜?wù)里面創(chuàng)建如下的應(yīng)用:
{
??"id": "nginx",
??"container": {
????"type": "DOCKER",
????"docker": {
??????"image": "nginx:1.7.7",
??????"network": "BRIDGE",
??????"portMappings": [
????????{ "hostPort": 0, "containerPort": 80, "servicePort": 10000 }
??????],
??????"forcePullImage":true
????}
??},
??"instances": 1,
??"cpus": 0.1,
??"mem": 65,
??"healthChecks": [{
??????"protocol": "HTTP",
??????"path": "/",
??????"portIndex": 0,
??????"timeoutSeconds": 10,
??????"gracePeriodSeconds": 10,
??????"intervalSeconds": 2,
??????"maxConsecutiveFailures": 10
??}],
??"labels":{
????"HAPROXY_GROUP":"external"
??}
}
在這個(gè)應(yīng)用里面,servicePort為10000則說明我們注冊(cè)到marathon-lb上的外部端口為10000, labels里面寫的是external,也即注冊(cè)到外部的負(fù)載均衡器上。
這個(gè)時(shí)候,我們?cè)L問public slave上的10000端口,就能看到啟動(dòng)的nginx的頁面http://54.254.148.129:10000/,內(nèi)部其他的應(yīng)用可以通過http://marathon-lb.marathon.mesos:10000來訪問這個(gè)nginx
如果我們?cè)L問public slave上的haproxy的配置頁面http://54.254.148.129:9090/haproxy?stats,可以看到如下的映射關(guān)系。
請(qǐng)點(diǎn)擊此處輸入圖片描述
對(duì)外marathon-lb監(jiān)聽10000端口,對(duì)內(nèi)映射為10.0.1.78上的20215端口,如果我們從服務(wù)頁面上查看,的確啟動(dòng)的nginx是監(jiān)聽20215端口的。
請(qǐng)點(diǎn)擊此處輸入圖片描述
接下來我們部署marathon-lb-autoscale,它監(jiān)控haproxy,發(fā)現(xiàn)RPS(request per seconds)超過一定的數(shù)目,就對(duì)應(yīng)用進(jìn)行彈性擴(kuò)展。
{
??"id": "marathon-lb-autoscale",
??"args":[
????"--marathon", "http://leader.mesos:8080",
????"--haproxy", "http://marathon-lb.marathon.mesos:9090",
????"--target-rps", "100",
????"--apps", "nginx_10000"
??],
??"cpus": 0.1,
??"mem": 16.0,
??"instances": 1,
??"container": {
????"type": "DOCKER",
????"docker": {
??????"image": "brndnmtthws/marathon-lb-autoscale",
??????"network": "HOST",
??????"forcePullImage":?true
????}
??}
}
接下來,我們部署應(yīng)用siege向nginx發(fā)送請(qǐng)求
{
??"id": "siege",
??"args":[
????"-d1",
????"-r1000",
????"-c100",
????"http://marathon-lb.marathon.mesos:10000/"
??],
??"cpus": 0.5,
??"mem": 16.0,
??"instances": 1,
??"container": {
????"type": "DOCKER",
????"volumes": [],
????"docker": {
??????"image": "yokogawa/siege",
??????"network": "HOST",
??????"privileged":?false,
??????"parameters": [],
??????"forcePullImage":?false
????}
??}
}
如果我們看haproxy的stats頁面,發(fā)現(xiàn)已經(jīng)有請(qǐng)求發(fā)過來了。這個(gè)時(shí)候我們?cè)黾觭iege到10,給nginx加壓。
請(qǐng)點(diǎn)擊此處輸入圖片描述
過一段時(shí)間就會(huì)發(fā)現(xiàn)marathon-lb-autoscale已經(jīng)有動(dòng)作了。
請(qǐng)點(diǎn)擊此處輸入圖片描述
將一個(gè)nginx變成8個(gè)nginx
請(qǐng)點(diǎn)擊此處輸入圖片描述
請(qǐng)點(diǎn)擊此處輸入圖片描述
當(dāng)我們將siege從10個(gè)變回0個(gè)的時(shí)候。
請(qǐng)點(diǎn)擊此處輸入圖片描述
第四、Minuteman
Minuteman是一個(gè)內(nèi)部的東西向的負(fù)載均衡器,可用于設(shè)置VIP,多個(gè)實(shí)例使用同一個(gè)VIP來進(jìn)行負(fù)載均衡。
請(qǐng)點(diǎn)擊此處輸入圖片描述
在創(chuàng)建服務(wù)的時(shí)候,選擇Load Balanced,則下面會(huì)出現(xiàn)一行地址:nginxdocker.marathon.l4lb.thisdcos.directory:80,這個(gè)就是minuteman分配的VIP。
當(dāng)服務(wù)創(chuàng)建好了之后,通過curl?http://nginxdocker.marathon.l4lb.thisdcos.directory:80就可以訪問這個(gè)服務(wù),但是我們?nèi)绻鹥ing這個(gè)域名卻是不通的,而且對(duì)于的IP地址也是很奇怪的IP地址,這個(gè)IP就是VIP.
請(qǐng)點(diǎn)擊此處輸入圖片描述
這是怎么做到的呢?minuteman的load balancer是基于Netfilter的,在dcos的slave節(jié)點(diǎn)上,我們能看到多出來了四個(gè)iptables規(guī)則。其中前兩個(gè)規(guī)則是在raw表里面的,后兩個(gè)規(guī)則是在filter表里面的。
-A PREROUTING -p tcp -m?set?--match-set?minuteman dst,dst -m tcp --tcp-flags FIN,SYN,RST,ACK SYN -j NFQUEUE --queue-balance 50:58
-A OUTPUT -p tcp -m?set?--match-set?minuteman dst,dst -m tcp --tcp-flags FIN,SYN,RST,ACK SYN -j NFQUEUE --queue-balance 50:58
-A FORWARD -p tcp -m?set?--match-set?minuteman dst,dst -m tcp --tcp-flags FIN,SYN,RST,ACK SYN -j REJECT --reject-with icmp-port-unreachable
-A OUTPUT -p tcp -m?set?--match-set?minuteman dst,dst -m tcp --tcp-flags FIN,SYN,RST,ACK SYN -j REJECT --reject-with icmp-port-unreachable
請(qǐng)點(diǎn)擊此處輸入圖片描述
根據(jù)iptbles的規(guī)則raw表中的規(guī)則會(huì)被先執(zhí)行,一旦到達(dá)了filter表的minuteman的包就都過濾掉了。
NFQUEUE的規(guī)則表示將對(duì)于包的處理權(quán)交給用戶態(tài)的一個(gè)進(jìn)程。--queue-balance表示會(huì)將包發(fā)給幾個(gè)queue,然后用戶態(tài)進(jìn)程會(huì)使用libnetfilter_queue連接到這些queue中,將包讀出來,根據(jù)包的內(nèi)容做決策后放回內(nèi)核進(jìn)行發(fā)送。
在每一個(gè)Mesos-Agent節(jié)點(diǎn)上都運(yùn)行這一個(gè)minuteman的進(jìn)程,監(jiān)聽這些queue,我們可以通過訪問API查看VIP的映射關(guān)系,curl http://localhost:61421/vips。
請(qǐng)點(diǎn)擊此處輸入圖片描述
我們可以看到VIP的11.112.175.214后面跟著兩個(gè)節(jié)點(diǎn)10.0.1.78:27003和10.0.1.78:4989,正好對(duì)應(yīng)nginx的兩個(gè)實(shí)例。
請(qǐng)點(diǎn)擊此處輸入圖片描述
請(qǐng)點(diǎn)擊此處輸入圖片描述
四、DC/OS的微服務(wù)及大數(shù)據(jù)的管理機(jī)制
DC/OS是基于Mesos的,Mesos的靈活框架機(jī)制可以使得DC/OS既能夠部署容器,也能夠部署大數(shù)據(jù)框架,大數(shù)據(jù)框架在不運(yùn)行任務(wù)的時(shí)候,幾乎不占用資源,從而真正實(shí)現(xiàn)微服務(wù)和大數(shù)據(jù)框架的資源共享。
前面我們部署容器的時(shí)候,都是自己準(zhǔn)備marathon的json進(jìn)行部署的,這就需要使用服務(wù)的人和設(shè)計(jì)服務(wù)的人同樣的專業(yè)。
DC/OS采用了一種package管理機(jī)制,將運(yùn)行一個(gè)微服務(wù)或者框架所需要的各種配置制作成模板,模板由專業(yè)人士制作好上傳到package repository,使用者就不需要那么專業(yè),只要運(yùn)行dcos package install安裝即可。
Mesosphere提供了官方的package repository,名為universe,地址為https://universe.mesosphere.com/repo,在github上可以找到對(duì)應(yīng)的代碼https://github.com/mesosphere/universe。
請(qǐng)點(diǎn)擊此處輸入圖片描述
對(duì)于一個(gè)package,往往包含下面的部分:
package.json:這里面保存了一些metadata的數(shù)據(jù),例如對(duì)于spark
"name": "spark",
"description": "Spark is a fast and general cluster computing system for Big Data. Documentation: https://docs.mesosphere.com/current/usage/service-guides/spark/",
"licenses": [
????{
????????"name": "Apache License Version 2.0",
????????"url": "https://raw.githubusercontent.com/apache/spark/master/LICENSE"
????}
],
"tags": [
????"bigdata",
????"mapreduce",
????"batch",
????"analytics"
],
config.json:保存一些配置項(xiàng),例如對(duì)于spark
"name": {
????"default": "spark",
????"description": "The Spark Dispatcher will register with Mesos with this as a framework name. This service will be available at http:///service//",
????"type": "string"
},
"cpus": {
????"default": 1,
????"description": "CPU shares",
????"minimum": 0.0,
????"type": "number"
},
"mem": {
????"default": 1024.0,
????"description": "Memory (MB)",
????"minimum": 1024.0,
????"type": "number"
},
"role": {
????"description": "The Spark Dispatcher will register with Mesos with this role.",
????"type": "string",
????"default": "*"
},
marathon.json.mustache:是一個(gè)模板,里面的一些變量會(huì)替換為config.json里面的內(nèi)容,最終變成可以直接發(fā)送給marathon的請(qǐng)求。以spark為例
"id": "{{service.name}}",
"cpus": {{service.cpus}},
"mem": {{service.mem}},
"container": {
????"type": "DOCKER",
????"docker": {
????????"image": "{{resource.assets.container.docker.spark_docker}}",
????????"network": "HOST",
????????"forcePullImage":?true
????}
},
resource.json:是一些資源,如image,tar.gz文件等
"assets": {
????"container": {
????????"docker": {
????????????"spark_docker": "mesosphere/spark:1.0.2-2.0.0"
????????}
????}
},
所有的這些配置都像模板一樣已經(jīng)預(yù)先寫好,安裝的時(shí)候界面上一點(diǎn),或者一行命令就安裝好了。
請(qǐng)點(diǎn)擊此處輸入圖片描述
當(dāng)然你如果點(diǎn)擊Advanced Installation,則所有的配置都可以定制化
請(qǐng)點(diǎn)擊此處輸入圖片描述
就像yum里面一樣,將mysql-server的yum包的制作者和mysql的使用者分開,普通用戶作為使用者,不需要了解太多的細(xì)節(jié),用就是了。
如果想在數(shù)據(jù)中心里面使用package管理,可以生成自己的local universe,里面放入自己的應(yīng)用,只要專業(yè)人士設(shè)計(jì)一次,便可以多次使用。也可以一次安裝多個(gè)軟件形成一個(gè)group,里面包含微服務(wù)的,也包含大數(shù)據(jù)的,兩者可以通過服務(wù)發(fā)現(xiàn)相互訪問。
我們?cè)谶@里先安裝一個(gè)spark的軟件
請(qǐng)點(diǎn)擊此處輸入圖片描述
最初安裝完畢spark,卻發(fā)現(xiàn)只有一個(gè)docker
請(qǐng)點(diǎn)擊此處輸入圖片描述
Spark不是一個(gè)集群計(jì)算框架嗎,怎么會(huì)只有一個(gè)Docker呢?這就是mesos對(duì)大數(shù)據(jù)框架管理的特殊之處。在spark不運(yùn)行任務(wù)的時(shí)候,就僅僅占用這一個(gè)docker,其實(shí)是一個(gè)框架。
請(qǐng)點(diǎn)擊此處輸入圖片描述
安裝過程如圖所示:
dcos package install spark會(huì)將請(qǐng)求提交給admin router
admin router會(huì)將請(qǐng)求提交給cosmos,也即package管理的服務(wù)
cosmos將config.json, resource.json, marathon.json組合成為一個(gè)marathon請(qǐng)求提交給marathon
marathon將請(qǐng)求交給mesos-master,然后交給mesos-agent
mesos-agent啟動(dòng)一個(gè)容器運(yùn)行spark
啟動(dòng)的spark容器會(huì)注冊(cè)到mesos里面成為一個(gè)新的framework
請(qǐng)點(diǎn)擊此處輸入圖片描述
真正運(yùn)行spark任務(wù)的時(shí)候,才會(huì)有其他占用資源的任務(wù)被創(chuàng)建出來。
dcos spark run --submit-args='-Dspark.mesos.coarse=true?--driver-cores 1 --driver-memory 1024M --classorg.apache.spark.examples.SparkPi https://downloads.mesosphere.com/spark/assets/spark-examples_2.10-1.4.0-SNAPSHOT.jar 30'

請(qǐng)點(diǎn)擊此處輸入圖片描述
Spark運(yùn)行過程如圖:
dcos spark run將任務(wù)提交給admin router
admin router將任務(wù)提交給spark framework
spark framework將任務(wù)提交給mesos-master
mesos-master將任務(wù)分發(fā)給mesos-agent進(jìn)行分別處理
任務(wù)運(yùn)行完畢后,所有mesos-agent上占用的資源又都釋放了。
正是這種模式,才實(shí)現(xiàn)微服務(wù)和大數(shù)據(jù)框架的共享資源,與此相對(duì)應(yīng)的是使用Docker來部署spark集群,然后集群自管理,不歸mesos管理。這樣在創(chuàng)建spark集群的時(shí)候,就需要指定spark worker占用的資源,比如16G,然而這16G資源則無論spark是否在計(jì)算,都會(huì)被占用,都不會(huì)被其他的框架使用。
五、DC/OS 1.8的新功能
對(duì)于最新的DC/OS 1.8,有一個(gè)博客https://dcos.io/blog/2016/introducing-dc-os-1-8-ga/index.html描述了最新的功能。
其中第一個(gè)重要的功能為Mesos 1.0 and the Universal Container Runtime,也即可以使用mesos-containerizer來運(yùn)行Docker的鏡像了。這也是DC/OS對(duì)于容器的管理越來越獨(dú)立的體現(xiàn)。
我們?cè)趍esos-agent所在的機(jī)器上可以查看
ip-10-0-1-78 dcos.target.wants_slave # ps aux | grep mesos-agent
root 1824 0.6 0.3 1069204 46948 ? Ssl Oct03 9:57 /opt/mesosphere/packages/mesos--19a545facb66e57dfe2bb905a001a58b7eaf6004/bin/mesos-agent
mesos-agent的配置在路徑/opt/mesosphere/packages/mesos--19a545facb66e57dfe2bb905a001a58b7eaf6004下面,在/opt/mesosphere/packages/mesos--19a545facb66e57dfe2bb905a001a58b7eaf6004/dcos.target.wants_slave/dcos-mesos-slave.service里面是mesos-slave的啟動(dòng)參數(shù)的設(shè)置,通過mesos的文檔,我們知道對(duì)于mesos的參數(shù)可以使用環(huán)境變量進(jìn)行設(shè)置。
ip-10-0-1-78 dcos.target.wants_slave # cat dcos-mesos-slave.service
[Unit]
Description=Mesos Agent: DC/OS Mesos Agent Service
[Service]
Restart=always
StartLimitInterval=0
RestartSec=5
KillMode=control-group
Delegate=true
LimitNOFILE=infinity
TasksMax=infinity
EnvironmentFile=/opt/mesosphere/environment
EnvironmentFile=/opt/mesosphere/etc/mesos-slave-common
EnvironmentFile=/opt/mesosphere/etc/mesos-slave
EnvironmentFile=/opt/mesosphere/etc/proxy.env
EnvironmentFile=-/opt/mesosphere/etc/mesos-slave-common-extras
EnvironmentFile=-/var/lib/dcos/mesos-slave-common
EnvironmentFile=-/var/lib/dcos/mesos-resources
EnvironmentFile=-/run/dcos/etc/mesos-slave
ExecStartPre=/bin/ping -c1 ready.spartan
ExecStartPre=/bin/ping -c1 leader.mesos
ExecStartPre=/opt/mesosphere/bin/bootstrap dcos-mesos-slave
ExecStartPre=/opt/mesosphere/bin/make_disk_resources.py /var/lib/dcos/mesos-resources
ExecStartPre=/bin/bash -c 'for?i?in?/proc/sys/net/ipv4/conf/*/rp_filter;?do?echo 2 > $i; echo -n "$i:?"; cat $i; done'
ExecStart=/opt/mesosphere/packages/mesos--19a545facb66e57dfe2bb905a001a58b7eaf6004/bin/mesos-agent
在文件/opt/mesosphere/etc/mesos-slave-common中配置了大量的mesos-agent的參數(shù)
MESOS_MASTER=zk://zk-1.zk:2181,zk-2.zk:2181,zk-3.zk:2181,zk-4.zk:2181,zk-5.zk:2181/mesos
MESOS_CONTAINERIZERS=docker,mesos
MESOS_LOG_DIR=/var/log/mesos
MESOS_MODULES_DIR=/opt/mesosphere/etc/mesos-slave-modules
MESOS_CONTAINER_LOGGER=org_apache_mesos_LogrotateContainerLogger
MESOS_ISOLATION=cgroups/cpu,cgroups/mem,disk/du,network/cni,filesystem/linux,docker/runtime,docker/volume
MESOS_DOCKER_VOLUME_CHECKPOINT_DIR=/var/lib/mesos/isolators/docker/volume
MESOS_IMAGE_PROVIDERS=docker
MESOS_NETWORK_CNI_CONFIG_DIR=/opt/mesosphere/etc/dcos/network/cni
MESOS_NETWORK_CNI_PLUGINS_DIR=/opt/mesosphere/active/cni/
MESOS_WORK_DIR=/var/lib/mesos/slave
MESOS_SLAVE_SUBSYSTEMS=cpu,memory
MESOS_EXECUTOR_ENVIRONMENT_VARIABLES=file:///opt/mesosphere/etc/mesos-executor-environment.json
MESOS_EXECUTOR_REGISTRATION_TIMEOUT=10mins
MESOS_CGROUPS_ENABLE_CFS=true
MESOS_CGROUPS_LIMIT_SWAP=false
MESOS_DOCKER_REMOVE_DELAY=1hrs
MESOS_DOCKER_STOP_TIMEOUT=20secs
MESOS_DOCKER_STORE_DIR=/var/lib/mesos/slave/store/docker
MESOS_GC_DELAY=2days
MESOS_HOSTNAME_LOOKUP=false
GLOG_drop_log_memory=false
默認(rèn)的mesos-containerizer的隔離只包括cpu和memory,然而在最新的mesos版本里面,多了provisioner這一層,在上面的配置里面隔離了MESOS_ISOLATION=cgroups/cpu,cgroups/mem,disk/du,network/cni,filesystem/linux,docker/runtime,docker/volume,從而可以啟動(dòng)docker的鏡像了。
第二個(gè)最重要的功能是CNI, container network interface。
請(qǐng)點(diǎn)擊此處輸入圖片描述
CNI要工作需要三部分:
首先DC/OS不需要外置的IPAM,而是由mesos-master的replicated_log負(fù)責(zé)管理分配IP地址,Mesos需要啟動(dòng)的時(shí)候,載入overlay network的modules。
在路徑/opt/mesosphere/etc/mesos-slave-modules下面有文件overlay_slave_modules.json
ip-10-0-1-78 mesos-slave-modules # cat overlay_slave_modules.json
{
??"libraries":
??[
????{
??????"file": "/opt/mesosphere/active/mesos-overlay-modules/lib/mesos/libmesos_network_overlay.so",
??????"modules":
????????[
??????????{
????????????"name": "com_mesosphere_mesos_OverlayAgentManager",
????????????"parameters" :
??????????????[
????????????????{
??????????????????"key": "agent_config",
??????????????????"value" : "/opt/mesosphere/etc/overlay/config/agent.json"
????????????????}
??????????????]
??????????}
????????]
?????}
??]
}
其次需要載入CNI isolator,這個(gè)在MESOS_ISOLATION這個(gè)環(huán)境變量里面已經(jīng)配置了。
最后還需要navstar服務(wù)來實(shí)現(xiàn)跨節(jié)點(diǎn)之間的IP互訪問
每個(gè)mesos-agent的機(jī)器上都有opt/mesosphere/packages/navstar--589afdaef03114a17576ee648ae433a052f7a4b9/,都會(huì)運(yùn)行一個(gè)navstar進(jìn)程。
每個(gè)機(jī)器上都會(huì)創(chuàng)建網(wǎng)卡d-dcos,如果Docker容器使用CNI獲取IP的容器都Attach到這個(gè)網(wǎng)卡上,而非docker0上。
每個(gè)機(jī)器上都會(huì)創(chuàng)建網(wǎng)卡m-dcos,如果mesos容器使用CNI獲取IP的容器都Attach到這個(gè)網(wǎng)卡上。
每臺(tái)機(jī)器的d-dcos和m-dcos的網(wǎng)段都不同。
每臺(tái)機(jī)器都會(huì)創(chuàng)建一個(gè)vtep1024的網(wǎng)卡,作為VTEP,背后是vxlan。
每臺(tái)機(jī)器都會(huì)創(chuàng)建默認(rèn)的路由表,從本節(jié)點(diǎn)連接到其他的節(jié)點(diǎn)默認(rèn)走vtep1024這個(gè)網(wǎng)卡。
9.0.0.0/24 via 44.128.0.1 dev vtep1024
9.0.1.0/24 via 44.128.0.2 dev vtep1024
9.0.3.0/24 via 44.128.0.4 dev vtep1024
對(duì)DC/OS的網(wǎng)絡(luò)的配置在/opt/mesosphere/etc/dcos/network/cni路徑下

請(qǐng)點(diǎn)擊此處輸入圖片描述
為了試驗(yàn)這兩個(gè)新的功能,我們首先創(chuàng)建一個(gè)使用CNI的Mesos容器,但是啟動(dòng)的是Docker的Image nginx
{
???"id":"nginxmesos",
???"cmd":"env; ip -o addr; sleep 3600",
???"cpus":0.10,
???"mem":512,
???"instances":1,
???"ipAddress":{
??????"networkName":"dcos"
???},
???"container":{
??????"type":"MESOS",
??????"docker":{
?????????"network":"USER",
?????????"image":"nginx",
?????????"portMappings":[
????????????{
????????????????"host_port": 0,
????????????????"container_port": 80,
????????????????"protocol": "tcp"
????????????}
?????????]
??????}
???}
}
在日志里面,打印出來容器的IP地址是m-dcos網(wǎng)段的。
請(qǐng)點(diǎn)擊此處輸入圖片描述
然后我們?cè)賳?dòng)一個(gè)使用CNI的Docker容器
{
???"id":"nginxmesos1",
???"cmd":"env; ip -o addr; sleep 3600",
???"cpus":0.10,
???"mem":512,
???"instances":1,
???"ipAddress":{
??????"networkName":"dcos"
???},
???"container":{
??????"type":"DOCKER",
??????"docker":{
?????????"network":"USER",
?????????"image":"nginx",
?????????"portMappings":[
????????????{
????????????????"host_port": 0,
????????????????"container_port": 80,
????????????????"protocol": "tcp"
????????????}
?????????]
??????}
???}
}
從日志我們看出,配置的IP是d-dcos網(wǎng)段的,而非docker0網(wǎng)段的。
請(qǐng)點(diǎn)擊此處輸入圖片描述
從Mesos上我們看出這兩個(gè)容器是在兩個(gè)節(jié)點(diǎn)上的
請(qǐng)點(diǎn)擊此處輸入圖片描述
登入Docker的容器,ping另外一個(gè)CNI的mesos的IP是沒有問題的。
ip-10-0-1-78 cni # docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
e7908deb3017 nginx "/bin/sh -c 'env; ip?" 28 minutes ago Up 28 minutes 80/tcp, 443/tcp mesos-b3fbe6d9-236a-4856-a986-9babbba9c02c-S2.e3c96fa7-b5ff-4af6-9099-bbed399c7c37
a992929fb0d1 nginx "nginx -g 'daemon off" 6 hours ago Up 6 hours 443/tcp, 0.0.0.0:4989->80/tcp mesos-b3fbe6d9-236a-4856-a986-9babbba9c02c-S2.fca41f8d-816c-49cd-9b19-ba059b95e885
8032756dd66e nginx "nginx -g 'daemon off" 6 hours ago Up 6 hours 443/tcp, 0.0.0.0:27003->80/tcp mesos-b3fbe6d9-236a-4856-a986-9babbba9c02c-S2.c0fdd3db-6f17-41d3-ab05-6f2d4d0bfa13
ip-10-0-1-78 cni # docker exec -it e7908deb3017 bash
root@e7908deb3017:/# ip addr
1: lo: mtu 65536 qdisc noqueue state UNKNOWN group?default?qlen 1
????link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
????inet 127.0.0.1/8 scope host lo
???????valid_lft forever preferred_lft forever
????inet6 ::1/128 scope host
???????valid_lft forever preferred_lft forever
51: eth0@if52: mtu 1420 qdisc noqueue state UP group?default
????link/ether 02:42:09:00:03:82 brd ff:ff:ff:ff:ff:ff
????inet 9.0.3.130/25 scope global eth0
???????valid_lft forever preferred_lft forever
????inet6 fe80::42:9ff:fe00:382/64 scope link
???????valid_lft forever preferred_lft forever
root@e7908deb3017:/# ping 9.0.2.13
PING 9.0.2.13 (9.0.2.13): 56 data bytes
64 bytes from 9.0.2.13: icmp_seq=0 ttl=62 time=0.709 ms
64 bytes from 9.0.2.13: icmp_seq=1 ttl=62 time=0.535 ms
長(zhǎng)按識(shí)別關(guān)注我們,每天都有精彩內(nèi)容分享哦!~