Docker网络和服务发现
【編者的話】 本文是《Docker網(wǎng)絡(luò)和服務(wù)發(fā)現(xiàn)》一書的全文,作者是Michael Hausenblas。本文介紹了Docker世界中的網(wǎng)絡(luò)和服務(wù)發(fā)現(xiàn)的工作原理,并提供了一系列解決方案。
?
前言
當(dāng)你開始使用Docker構(gòu)建應(yīng)用的時(shí)候,對(duì)于Docker的能力和它帶來(lái)的機(jī)會(huì),你會(huì)感到很興奮。它可以同時(shí)在開發(fā)環(huán)境和生產(chǎn)環(huán)境中運(yùn)行,只需要將一切打包進(jìn)一個(gè)Docker鏡像中,然后通過(guò)Docker Hub分發(fā)鏡像,這是很直接了當(dāng)?shù)摹D銜?huì)發(fā)現(xiàn)以下過(guò)程很令人滿意:你可以快速地將現(xiàn)有的應(yīng)用(如Python應(yīng)用)移植到Docker中,將該容器與另一個(gè)數(shù)據(jù)庫(kù)容器(如PostgreSQL)連接。但是,你不會(huì)想手動(dòng)啟動(dòng)一個(gè)Docker容器,也不會(huì)想自己去實(shí)現(xiàn)一個(gè)系統(tǒng)來(lái)監(jiān)控運(yùn)行中的容器和重啟未運(yùn)行的容器。
此時(shí),你會(huì)意識(shí)到兩個(gè)相互關(guān)聯(lián)的挑戰(zhàn):網(wǎng)絡(luò)和服務(wù)發(fā)現(xiàn)。不幸的是,說(shuō)得好聽(tīng)一點(diǎn),這兩個(gè)領(lǐng)域都是新興的課題;說(shuō)得難聽(tīng)一點(diǎn),在這兩個(gè)領(lǐng)域里,還有很多不確定的內(nèi)容,也缺乏最佳實(shí)踐。幸運(yùn)的是,在海量的博客和文章中,分散著各種各樣的“秘方”。
?
?
本書
因此,我對(duì)自己說(shuō):如果有人寫本書,可以介紹這些主題,并提供一些基本的指導(dǎo),對(duì)于每項(xiàng)技術(shù)給讀者指引正確的方向,那該多好啊。
那個(gè)“人”注定是我, 在本書里,我將介紹Docker容器網(wǎng)絡(luò)和服務(wù)發(fā)現(xiàn)領(lǐng)域中的挑戰(zhàn)和現(xiàn)有的解決方案。 我想讓大家了解以下三點(diǎn):
?
?
- 服務(wù)發(fā)現(xiàn)和容器編排就像一枚硬幣的兩面。
- 對(duì)于Docker網(wǎng)絡(luò),如果沒(méi)有正確的理解和完善的策略,那就糟糕了。
- 網(wǎng)絡(luò)和服務(wù)發(fā)現(xiàn)領(lǐng)域還很年輕。你會(huì)發(fā)現(xiàn),剛開始你還在學(xué)習(xí)一套技術(shù),過(guò)一段時(shí)間,就會(huì)“換擋”,嘗試另一套技術(shù)。不要緊張,這是很正常的。在我看來(lái),在形成標(biāo)準(zhǔn)和市場(chǎng)穩(wěn)定之前,還會(huì)有兩三年時(shí)間。
編排和調(diào)度
嚴(yán)格來(lái)講,編排是比調(diào)度更廣泛的一個(gè)概念:編排包含了調(diào)度,同時(shí)也包含其他內(nèi)容。例如,容器的故障重啟(可能是由于容器本身不健康,也可能是宿主機(jī)出了故障)。而調(diào)度僅僅是指,決定哪個(gè)容器運(yùn)行在哪個(gè)宿主機(jī)上的過(guò)程。在本書中,我會(huì)無(wú)差別地使用這兩個(gè)術(shù)語(yǔ)。
我這么做的原因是:第一,在IETF RFC和NIST標(biāo)準(zhǔn)中并沒(méi)有對(duì)這兩個(gè)概念的官方定義;第二,在不同公司的市場(chǎng)宣傳中,往往會(huì)故意混淆它們,因此我希望你能對(duì)此有所準(zhǔn)備。然而,Joe Beda(前Google和Kubernetes的策劃者)對(duì)于該問(wèn)題發(fā)表了一篇相當(dāng)不錯(cuò)的文章:?What Makes a Container Cluster?,你可以更深入地了解一下。
?
?
你
我希望,本書的讀者是:
?
?
- 開發(fā)者們,正在使用Docker;
- 網(wǎng)絡(luò)Ops,正在為熱情的開發(fā)者所帶來(lái)的沖擊做準(zhǔn)備;
- (企業(yè))軟件架構(gòu)師,正在將現(xiàn)有負(fù)載遷移到Docker,或者使用Docker開始一項(xiàng)新項(xiàng)目;
- 最后但同樣重要的是,我相信,分布式應(yīng)用的開發(fā)者、SRE和后端工程師們也能從其中獲取一些價(jià)值。
需要注意的是,本書不是一本動(dòng)手實(shí)踐(hands-on)的書籍(除了第二章的Docker網(wǎng)絡(luò)部分),更像是一本指導(dǎo)。當(dāng)你計(jì)劃實(shí)施一個(gè)基于Docker的部署時(shí),你可以參考本書來(lái)做出一個(gè)明智合理的決定。閱讀本書的另一種方式是,添加大量注釋和書簽(a heavily annotated bookmark collection)。
?
?
我
我在一個(gè)很酷的創(chuàng)業(yè)公司Mesosphere, Inc.(Apache Mesos背后的商業(yè)公司)工作,主要的工作內(nèi)容是幫助DevOps充分利用Mesos。雖然我有偏見(jiàn)地認(rèn)為Mesos是目前進(jìn)行大規(guī)模集群調(diào)度的最佳選擇,但是我仍然會(huì)盡我最大的努力來(lái)確保這種偏愛(ài)不會(huì)影響對(duì)于各項(xiàng)技術(shù)的介紹。
?
?
致謝
向Mesosphere同事們James DeFelice和Stefan Schimanski(來(lái)自Kubernetes組)致謝,他們很耐心地回答了我關(guān)于Kubernetes網(wǎng)絡(luò)的問(wèn)題。向我的Mesosphere同事們Sebastien Pahl和Tim Fall(原Docker同事)致謝,我非常感謝你們關(guān)于Docker網(wǎng)絡(luò)的建議。也很感謝另一個(gè)Mesos同事Mohit Soni,在百忙之中他提供了很多反饋。
進(jìn)一步地, 我要感謝Medallia的Thorvald Natvig,他的講話Velocity NYC 2015促使我深入地思考了網(wǎng)絡(luò)這一領(lǐng)域,他也很友善地和我討論Medallia生產(chǎn)環(huán)境中使用Docker/Mesos/Aurora的經(jīng)驗(yàn)和教訓(xùn)。
很感謝Adrian Mouat(容器解決方案)和Diogo Mónica(Docker, Inc.)通過(guò)Twitter回答問(wèn)題,尤其是在普通人睡覺(jué)的時(shí)候,花了數(shù)小時(shí)回答了我的問(wèn)題。
我也很感謝來(lái)自Chris Swan的反饋,他提供了明確可操作的評(píng)論。通過(guò)解決他的問(wèn)題,我相信本書變得更有針對(duì)性了。
在本書的寫作過(guò)程中,來(lái)自Google的Mandy Waite提供了很多有用的反饋,特別是Kubernetes,我很感謝這一點(diǎn)。我也很感激Tim Hockin(Google)的支持,他幫助我澄清了很多關(guān)于Docker網(wǎng)絡(luò)特性和Kubernetes的疑惑。
感謝Matthias Bauer對(duì)于本書的草稿提出的寶貴意見(jiàn)。
非常感謝我的O’Reilly編輯Brian Anderson。從我們討論草稿開始,你一直都非常支持我,很高效,也很有趣。非常榮幸和您一起工作。
最后重要的一點(diǎn)是,對(duì)于我的家庭要致以最深刻的謝意:我的“陽(yáng)光”Saphira,我的“運(yùn)動(dòng)女孩”Ranya,我的兒子和“Minecraft大師”Iannis,以及一直支持我的妻子Anneliese。如果沒(méi)有你們的支持,我是不可能完成本書的。
?
?
動(dòng)機(jī)
2012年2月,Randy Bias發(fā)表了一篇談話,名為開放和可擴(kuò)展云架構(gòu),提出了pets和cattle兩種文化基因的碰撞。
?
?
- 基礎(chǔ)設(shè)施的pets方法(pets approach to infrastructure),每臺(tái)機(jī)器或虛擬機(jī)被當(dāng)做一個(gè)個(gè)體,會(huì)分配一個(gè)名字,各個(gè)應(yīng)用被靜態(tài)地部署在各個(gè)機(jī)器上。例如:?db-prod-2是生產(chǎn)環(huán)境中的一臺(tái)數(shù)據(jù)庫(kù)服務(wù)器。應(yīng)用是手動(dòng)部署的,當(dāng)一臺(tái)機(jī)器出故障時(shí),你需要修復(fù)它,并把應(yīng)用手動(dòng)部署到另一臺(tái)機(jī)器上。在非云原生應(yīng)用時(shí)代(non-cloud-native era),這種方法通常占據(jù)著主導(dǎo)地位。
- 基礎(chǔ)設(shè)施的cattle方法(cattle approach to infrastructure),所有的機(jī)器都是無(wú)名的、完全類似的(modulo hardware upgrades),它們只有編號(hào),沒(méi)有名字。應(yīng)用是自動(dòng)部署到機(jī)器群中的任意一臺(tái)。當(dāng)其中一臺(tái)機(jī)器發(fā)生故障時(shí),你不需要立刻處理它,只要在方便的時(shí)候更換故障機(jī)器(或者它的一部分,如一塊損壞的HDD)。
盡管這些文化基因(meme)最初是針對(duì)虛擬機(jī)的,但是我們這里會(huì)將cattle方法套用在容器的基礎(chǔ)架構(gòu)上。
?
?
Go Cattle!
在基礎(chǔ)設(shè)施中,使用cattle方法的一大好處就是,你可以在商用硬件上進(jìn)行水平擴(kuò)展。
這樣一來(lái),你就可以有很大的彈性來(lái)實(shí)施混合云。只要你愿意,一部分可以部署在premise環(huán)境中,一部分部署在公有云上,也可以部署在不同的云提供商的IaaS架構(gòu)上。
更重要的是,從一名運(yùn)維者的角度上來(lái)看,cattle方法可以保證一個(gè)相當(dāng)好的睡眠質(zhì)量。因?yàn)槟阍僖膊粫?huì)像pets方法中那樣,凌晨3點(diǎn)被叫起來(lái)去更換一塊壞了的HDD或者將應(yīng)用重新部署到另一臺(tái)服務(wù)器上。
然而,cattle方法也帶來(lái)了一些挑戰(zhàn),主要包括以下兩個(gè)方面:
?
?
社交挑戰(zhàn)(Social challenges)
我敢說(shuō),大部分挑戰(zhàn)會(huì)來(lái)自于社交方面:我應(yīng)該怎么說(shuō)服我的老板呢?我怎么讓CTO買我的賬呢?我的同事們會(huì)反對(duì)這種新的做法嗎?這是不是意味著我們只需要更少的人來(lái)維護(hù)基礎(chǔ)架構(gòu)?現(xiàn)在,對(duì)于這個(gè)問(wèn)題,我還不能提供一個(gè)完整有效的解決方案。你可以買一本《鳳凰項(xiàng)目》,從中你可能可以找到答案。
?
技術(shù)挑戰(zhàn)(Technical challenges)
這個(gè)方面主要包括:機(jī)器的準(zhǔn)備機(jī)制(provisioning mechanism)如何選擇(例如,使用Ansible來(lái)部署Mesos Agents);在容器之間、在容器和外界之間如何通信;如何保證容器的自動(dòng)部署并能被尋址(consequently findable)。
?
Docker網(wǎng)絡(luò)和服務(wù)發(fā)現(xiàn)棧
我們?cè)趫D1-1中描述了整個(gè)技術(shù)棧,包括以下內(nèi)容:
?
?
底層的網(wǎng)絡(luò)層(The low-level networking layer)
這一層包括一系列網(wǎng)絡(luò)工具:?iptables、路由、IPVLAN和Linux命名空間。你通常不需要知道其中的細(xì)節(jié),除非你是在網(wǎng)絡(luò)組,但是你需要意識(shí)到這一點(diǎn)。關(guān)于這一課題的更多信息,可以參考Docker網(wǎng)絡(luò)基礎(chǔ)。
?
Docker網(wǎng)絡(luò)層
這一層封裝了底層的網(wǎng)絡(luò)層,提供各種抽象模型,例如單主機(jī)橋網(wǎng)絡(luò)模式、多主機(jī)的每個(gè)容器一個(gè)IP地址的解決方案。在第2章和第3章中有相關(guān)介紹。
?
服務(wù)發(fā)現(xiàn)層/容器編排層
這里,我們將容器調(diào)度定義為通過(guò)底層提供的基本原語(yǔ)(primitives)決定將容器放在哪里。第4章提到了服務(wù)發(fā)現(xiàn)的必要背景,第5章從容器編排的角度講解了網(wǎng)絡(luò)和服務(wù)發(fā)現(xiàn)。
軟件定義網(wǎng)絡(luò)(SDN)
SDN真的是一個(gè)市場(chǎng)術(shù)語(yǔ)(umbrella term或者marketing term),它可以提供VM帶來(lái)的網(wǎng)絡(luò)優(yōu)勢(shì),就像裸機(jī)服務(wù)器(bare-metal servers)一樣。網(wǎng)絡(luò)管理團(tuán)隊(duì)會(huì)變得更加敏捷,對(duì)商業(yè)需求的變化反應(yīng)更加迅速。另一種看法是:SDN是一種使用軟件來(lái)定義網(wǎng)絡(luò)的配置方式,可能是通過(guò)API構(gòu)建、通過(guò)NFV構(gòu)建,或者由Docker網(wǎng)絡(luò)來(lái)提供SDN。
如果你是一名開發(fā)者或架構(gòu)師,我建議你看一下Cisco對(duì)于該課題的觀點(diǎn)和SDxCentral的文章What’s Software-Defined Networking (SDN)?。
?
圖 1-1
如果你在網(wǎng)絡(luò)運(yùn)維組的話,你可能已經(jīng)準(zhǔn)備好進(jìn)入下一章了。然而,如果你是架構(gòu)師或者開發(fā)者的話,對(duì)于網(wǎng)絡(luò)知識(shí)可能有點(diǎn)生疏了,我建議你讀一下Linux Network Administrators Guide來(lái)復(fù)習(xí)一下相關(guān)知識(shí)。
?
我需要All-In嗎?
在各種會(huì)議和用戶組中,我經(jīng)常遇到一些人,他們對(duì)于容器領(lǐng)域的機(jī)會(huì)非常興奮,同時(shí)他們也擔(dān)心在從容器中受益之前需要投入多少。以下的表格是對(duì)于我了解的各種部署的非正式的總結(jié)(按照階段不同排序)。
?
?
需要注意的是,不是所有的例子都使用Docker容器(顯而易見(jiàn)的是,Google并不使用Docker容器)。其中,某些正在著手使用Docker,例如,在ad-hoc階段;某些正在轉(zhuǎn)向full-down階段,例如Uber,請(qǐng)看ContainerSched 2015 London中的演講。最后重要的一點(diǎn)是,這些階段與部署的大小是沒(méi)有必然關(guān)系的。例如,Gutefrage.de只有六臺(tái)裸機(jī)服務(wù)器,仍然使用Apache Mesos來(lái)管理它們。?
在繼續(xù)之前,還有最后一點(diǎn):到目前為止,你可能已經(jīng)注意到了我們處理的是分布式系統(tǒng)。由于我們總是希望將容器部署到一個(gè)集群中,我強(qiáng)烈建議你讀一下分布式計(jì)算的謬論,以防你不熟悉這一主題。
現(xiàn)在言歸正傳,讓我們進(jìn)入Docker網(wǎng)絡(luò)這一主題。
?
Docker網(wǎng)絡(luò)基礎(chǔ)
在我們進(jìn)入網(wǎng)絡(luò)細(xì)節(jié)之前,我們先來(lái)看一看在單主機(jī)上發(fā)生了什么。Docker容器需要運(yùn)行在一臺(tái)宿主機(jī)上,可以是一臺(tái)物理機(jī)(on-premise數(shù)據(jù)中心中的裸機(jī)服務(wù)器),也可以是on-prem或云上的一臺(tái)虛擬機(jī)。就像圖2-1中描述的那樣,宿主機(jī)上運(yùn)行了Docker的daemon進(jìn)程和客戶端,一方面可以與Docker registry交互,另一方面可以啟動(dòng)、關(guān)閉和審查容器。
?
?
圖 2-1
宿主機(jī)和容器的關(guān)系是1:N,這以為這一臺(tái)宿主機(jī)上可以運(yùn)行多個(gè)容器。例如,從Facebook的報(bào)告來(lái)看,取決于機(jī)器的能力,每臺(tái)宿主機(jī)上平均可以運(yùn)行10到40個(gè)容器。另一個(gè)數(shù)據(jù)是:在Mesosphere,我們發(fā)現(xiàn),在裸機(jī)服務(wù)器上的各種負(fù)載測(cè)試中,每臺(tái)宿主機(jī)上不超過(guò)250個(gè)容器是可能的。
無(wú)論你是在單主機(jī)上進(jìn)行部署,還是在集群上部署,你總得和網(wǎng)絡(luò)打交道:
?
- 對(duì)于大多數(shù)單主機(jī)部署來(lái)說(shuō),問(wèn)題歸結(jié)于是使用共享卷進(jìn)行數(shù)據(jù)交換,還是使用網(wǎng)絡(luò)(基于HTTP或者其他的)進(jìn)行數(shù)據(jù)交換。盡管Docker數(shù)據(jù)卷很容易使用,它也引入了緊耦合,這意味著很難將單主機(jī)部署轉(zhuǎn)化為多主機(jī)部署。自然地,共享卷的優(yōu)勢(shì)是速度。
- 在多主機(jī)部署中,你需要考慮兩個(gè)方面:單主機(jī)上的容器之間如何通信和多主機(jī)之間的通信路徑是怎樣的。性能考量和安全方面都有可能影響你的設(shè)計(jì)決定。多主機(jī)部署通常是很有必要的,原因是單主機(jī)的能力有限(請(qǐng)看前面關(guān)于宿主機(jī)上容器的平均數(shù)量和最大數(shù)量的討論),也可能是因?yàn)樾枰渴鸱植际较到y(tǒng),例如Apache Spark、HDFS和Cassandra。
分布式系統(tǒng)和數(shù)據(jù)本地化(Distributed Systems and Data Locality)
使用分布式系統(tǒng)(計(jì)算或存儲(chǔ))的基本想法是想從并行處理中獲利,通常伴隨著數(shù)據(jù)本地化。數(shù)據(jù)本地化,我指的是將代碼轉(zhuǎn)移到數(shù)據(jù)所在地的原則,而不是傳統(tǒng)的、其他的方式。考慮下以下的場(chǎng)景:如果你的數(shù)據(jù)集是TB級(jí)的,而代碼是MB級(jí)的,那么在集群中移動(dòng)代碼比傳輸TB級(jí)數(shù)據(jù)更高效。除了可以并行處理數(shù)據(jù)之外,分布式系統(tǒng)還可以提供容錯(cuò)性,因?yàn)橄到y(tǒng)中的一部分可以相對(duì)獨(dú)立地工作。
本章主要討論單主機(jī)中的網(wǎng)絡(luò),在第3章中,我們將介紹多主機(jī)場(chǎng)景。
簡(jiǎn)單地說(shuō),Docker網(wǎng)絡(luò)是原生的容器SDN解決方案。總而言之,Docker網(wǎng)絡(luò)有四種模式:橋模式,主機(jī)模式,容器模式和無(wú)網(wǎng)絡(luò)模式。我們會(huì)詳細(xì)地討論單主機(jī)上的各種網(wǎng)絡(luò)模式,在本章的最后,我們還會(huì)討論一些常規(guī)主題,比如安全。
?
?
bridge模式網(wǎng)絡(luò)
在該模式(見(jiàn)圖2-2)中,Docker守護(hù)進(jìn)程創(chuàng)建了一個(gè)虛擬以太網(wǎng)橋docker0,附加在其上的任何網(wǎng)卡之間都能自動(dòng)轉(zhuǎn)發(fā)數(shù)據(jù)包。默認(rèn)情況下,守護(hù)進(jìn)程會(huì)創(chuàng)建一對(duì)對(duì)等接口,將其中一個(gè)接口設(shè)置為容器的eth0接口,另一個(gè)接口放置在宿主機(jī)的命名空間中,從而將宿主機(jī)上的所有容器都連接到這個(gè)內(nèi)部網(wǎng)絡(luò)上。同時(shí),守護(hù)進(jìn)程還會(huì)從網(wǎng)橋的私有地址空間中分配一個(gè)IP地址和子網(wǎng)給該容器。
例2-1
?
?
$?docker?run?-d?-P?--net=bridge?nginx:1.9.1 $?docker?ps CONTAINER?ID???IMAGE??????????????????COMMAND????CREATED STATUS?????????PORTS??????????????????NAMES 17d447b7425d???nginx:1.9.1????????????nginx?-g???19?seconds?ago Up?18?seconds??0.0.0.0:49153->443/tcp,0.0.0.0:49154->80/tcp??trusting_feynman?
?
注意:因?yàn)閎ridge模式是Docker的默認(rèn)設(shè)置,所以你也可以使用docker run -d -P nginx:1.9.1。如果你沒(méi)有使用-P(發(fā)布該容器暴露的所有端口)或者-p host_port:container_port(發(fā)布某個(gè)特定端口),IP數(shù)據(jù)包就不能從宿主機(jī)之外路由到容器中。
?
?
圖 2-2
?
?
小技巧:在生產(chǎn)環(huán)境中,我建議使用Docker的host模式(將會(huì)在下一小節(jié)Host模式網(wǎng)路中討論),并輔以第3章中的某個(gè)SDN解決方案。進(jìn)一步地,為了控制容器間的網(wǎng)絡(luò)通信,你可以使用flags參數(shù):--iptables和-icc。
?
?
Host模式網(wǎng)絡(luò)
該模式將禁用Docker容器的網(wǎng)絡(luò)隔離。因?yàn)槿萜鞴蚕砹怂拗鳈C(jī)的網(wǎng)絡(luò)命名空間,直接暴露在公共網(wǎng)絡(luò)中。因此,你需要通過(guò)端口映射(port mapping)來(lái)進(jìn)行協(xié)調(diào)。
?
例2-2 $?docker?run?-d?--net=host?ubuntu:14.04?tail?-f?/dev/null $?ip?addr?|?grep?-A?2?eth0: 2:?eth0:?<BROADCAST,MULTICAST,UP,LOWER_UP>?mtu?9001?qdisc?mq?state?UP?group?default?qlen?1000 link/ether?06:58:2b:07:d5:f3?brd?ff:ff:ff:ff:ff:ff inet?**10.0.7.197**/22?brd?10.0.7.255?scope?global?dynamic?eth0$?docker?ps CONTAINER?ID??IMAGE?????????COMMAND??CREATED STATUS????????PORTS?????????NAMES b44d7d5d3903??ubuntu:14.04??tail?-f??2?seconds?ago Up?2?seconds????????????????jovial_blackwell $?docker?exec?-it?b44d7d5d3903?ip?addr 2:?eth0:?<BROADCAST,MULTICAST,UP,LOWER_UP>?mtu?9001?qdisc?mq?state?UP?group?default?qlen?1000 link/ether?06:58:2b:07:d5:f3?brd?ff:ff:ff:ff:ff:ff inet?**10.0.7.197**/22?brd?10.0.7.255?scope?global?dynamic?eth0
我們可以從例2-2中看到:容器和宿主機(jī)具有相同的IP地址10.0.7.197。
在圖2-3中,我們可以看到:當(dāng)使用host模式網(wǎng)絡(luò)時(shí),容器實(shí)際上繼承了宿主機(jī)的IP地址。該模式比bridge模式更快(因?yàn)闆](méi)有路由開銷),但是它將容器直接暴露在公共網(wǎng)絡(luò)中,是有安全隱患的。
?
圖 2-3
?
Container模式網(wǎng)絡(luò)
該模式會(huì)重用另一個(gè)容器的網(wǎng)絡(luò)命名空間。通常來(lái)說(shuō),當(dāng)你想要自定義網(wǎng)絡(luò)棧時(shí),該模式是很有用的。實(shí)際上,該模式也是Kubernetes使用的網(wǎng)絡(luò)模式,你可以在這里了解更多內(nèi)容。
例2-3
?
?
$?docker?run?-d?-P?--net=bridge?nginx:1.9.1 $?docker?ps CONTAINER?ID??IMAGE????????COMMAND???CREATED?????????STATUS PORTS??????????????????????NAMES eb19088be8a0??nginx:1.9.1??nginx?-g??3?minutes?ago???Up?3?minutes 0.0.0.0:32769->80/tcp, 0.0.0.0:32768->443/tcp?????admiring_engelbart $?docker?exec?-it?admiring_engelbart?ip?addr 8:?eth0@if9:?<BROADCAST,MULTICAST,UP,LOWER_UP>?mtu?9001?qdisc?noqueue?state?UP?group?default link/ether?02:42:ac:11:00:03?brd?ff:ff:ff:ff:ff:ff inet?**172.17.0.3**/16?scope?global?eth0$?docker?run?-it?--net=container:admiring_engelbart?ubuntu:14.04?ip?addr ... 8:?eth0@if9:?<BROADCAST,MULTICAST,UP,LOWER_UP>?mtu?9001?qdisc?noqueue?state?UP?group?default link/ether?02:42:ac:11:00:03?brd?ff:ff:ff:ff:ff:ff inet?**172.17.0.3**/16?scope?global?eth0
結(jié)果(例2-3)顯示:第二個(gè)容器使用了--net=container參數(shù),因此和第一個(gè)容器admiring_engelbart具有相同的IP地址172.17.0.3。
?
None模式網(wǎng)絡(luò)
該模式將容器放置在它自己的網(wǎng)絡(luò)棧中,但是并不進(jìn)行任何配置。實(shí)際上,該模式關(guān)閉了容器的網(wǎng)絡(luò)功能,在以下兩種情況下是有用的:容器并不需要網(wǎng)絡(luò)(例如只需要寫磁盤卷的批處理任務(wù));你希望自定義網(wǎng)絡(luò),在第3章中有很多選項(xiàng)使用了該模式。
例2-4
?
?
$?docker?run?-d?-P?--net=none?nginx:1.9.1 $?docker?ps CONTAINER?ID??IMAGE??????????COMMAND???CREATED STATUS????????PORTS??????????NAMES d8c26d68037c??nginx:1.9.1????nginx?-g??2?minutes?ago Up?2?minutes?????????????????grave_perlman $??docker?inspect?d8c26d68037c?|?grep?IPAddress "IPAddress":?"", "SecondaryIPAddresses":?null,
在例2-4中可以看到,恰如我們所料,網(wǎng)絡(luò)沒(méi)有任何配置。
你可以在Docker官方文檔中讀到更多關(guān)于Docker網(wǎng)絡(luò)的配置。
?
?
注意:本書中的所有Docker命令都是在CoreOS環(huán)境中執(zhí)行的,Docker客戶端和服務(wù)端的版本都是1.7.1。
?
?
更多話題
在本章中,我們了解了Docker單主機(jī)網(wǎng)絡(luò)的四種基本模式。現(xiàn)在我們討論下你應(yīng)該了解的其他主題(這與多主機(jī)部署也是相關(guān)的):
?
分配IP地址
頻繁大量的創(chuàng)建和銷毀容器時(shí),手動(dòng)分配IP地址是不能接受的。bridge模式可以在一定程度上解決這個(gè)問(wèn)題。為了防止本地網(wǎng)絡(luò)上的ARP沖突,Docker Daemon會(huì)根據(jù)分配的IP地址生成一個(gè)隨機(jī)地MAC地址。在下一章中,我們會(huì)再次討論分配地址的挑戰(zhàn)。
?
分配端口
你會(huì)發(fā)現(xiàn)有兩大陣營(yíng):固定端口分配(fixed-port-allocation)和動(dòng)態(tài)端口分配(dynamically-port-allocation)。每個(gè)服務(wù)或者應(yīng)用可以有各自的分配方法,也可以是作為全局的策略,但是你必須做出自己的判斷和決定。請(qǐng)記住,bridge模式中,Docker會(huì)自動(dòng)分配UDP或TCP端口,并使其可路由。
?
網(wǎng)絡(luò)安全
Docker可以開啟容器間通信(意味著默認(rèn)配置--icc=true),也就是說(shuō),宿主機(jī)上的所有容器可以不受任何限制地相互通信,這可能導(dǎo)致拒絕服務(wù)攻擊。進(jìn)一步地,Docker可以通過(guò)--ip_forward和--iptables兩個(gè)選項(xiàng)控制容器間、容器和外部世界的通信。你應(yīng)該了解這些選項(xiàng)的默認(rèn)值,并讓網(wǎng)絡(luò)組根據(jù)公司策略設(shè)置Docker進(jìn)程。可以讀一下StackEngine的Boyd Hemphill寫的文章Docker security analysis。
另一個(gè)網(wǎng)絡(luò)安全方面是線上加密(on-the-wire encryption),通常是指RFC 5246中定義的TLS/SSL。注意,在寫本書時(shí),這一方面還很少被討論,實(shí)際上,只有兩個(gè)系統(tǒng)(下一章會(huì)詳細(xì)討論)提供了這個(gè)特性:Weave使用NACl,OpenVPN是基于TLS的。根據(jù)我從Docker的安全負(fù)責(zé)人Diogo Mónica那里了解的情況,v1.9之后可能加入線上加密功能。
最后,可以讀一下Adrian Mouat的Using Docker,其中詳細(xì)地介紹了網(wǎng)絡(luò)安全方面。
?
?
小技巧: 自動(dòng)Docker安全檢查 為了對(duì)部署在生產(chǎn)環(huán)境中的Docker容器進(jìn)行安全檢查,我強(qiáng)烈建議使用The Docker Bench for Security。現(xiàn)在,我們對(duì)單主機(jī)場(chǎng)景有了一個(gè)基本的了解,讓我們繼續(xù)看一下更有效的案例:多主機(jī)網(wǎng)絡(luò)環(huán)境。
?
?
?
Docker多主機(jī)網(wǎng)絡(luò)
只要是在單主機(jī)上使用Docker的話,那么上一章中介紹的技術(shù)就足夠了。然而,如果一臺(tái)宿主機(jī)的能力不足以應(yīng)付工作負(fù)載,要么買一個(gè)更高配置的宿主機(jī)(垂直擴(kuò)展),要么你添加更多同類型的機(jī)器(水平擴(kuò)展)。
對(duì)于后者,你會(huì)搭建一個(gè)集群。那么,就出現(xiàn)了一系列問(wèn)題:不同宿主機(jī)上的容器之間如何相互通信?如何控制容器間、容器和外部世界之間的通信?怎么保存狀態(tài),如IP地址分配、集群內(nèi)保持一致性等?如何與現(xiàn)有的網(wǎng)絡(luò)基礎(chǔ)架構(gòu)結(jié)合?安全策略呢?
為了解決這些問(wèn)題,在本章中,我們會(huì)討論多主機(jī)網(wǎng)絡(luò)的各種技術(shù)。
?
?
?
注意:對(duì)于本章中介紹的各種選項(xiàng),請(qǐng)記住Docker信奉的是“batteries included but replaceable”,也就是說(shuō),總會(huì)有一個(gè)默認(rèn)功能(如網(wǎng)絡(luò)、服務(wù)發(fā)現(xiàn)),但是你可以使用其他方案來(lái)替代。
?
?
Overlay
2015年3月,Docker, Inc.收購(gòu)了軟件定義網(wǎng)絡(luò)(SDN)的創(chuàng)業(yè)公司SocketPlane,并更名為Docker Overlay驅(qū)動(dòng),作為多主機(jī)網(wǎng)絡(luò)的默認(rèn)配置(在Docker 1.9以后)。Overlay驅(qū)動(dòng)通過(guò)點(diǎn)對(duì)點(diǎn)(peer-to-peer)通信擴(kuò)展了通常的bridge模式,并使用一個(gè)可插拔的key-value數(shù)據(jù)庫(kù)后端(如Consul、etcd和ZooKeeper)來(lái)分發(fā)集群狀態(tài)。
?
Flannel
CoreOS?Flannel是一個(gè)虛擬網(wǎng)絡(luò),分配給每個(gè)宿主機(jī)一個(gè)子網(wǎng)。集群中的每個(gè)容器(或者說(shuō)是Kubernetes中的pod)都有一個(gè)唯一的、可路由的IP地址,并且支持以下一系列后端:VXLAN、AWS VPC和默認(rèn)的2層UDP overlay網(wǎng)絡(luò)。flannel的優(yōu)勢(shì)是它降低了端口映射的復(fù)雜性。例如,Red Hat的Atomic項(xiàng)目使用的就是flannel。
?
?
Weave
Weaveworks?Weave創(chuàng)建了一個(gè)虛擬網(wǎng)絡(luò),用來(lái)連接部署在多主機(jī)上的Docker容器。應(yīng)用使用網(wǎng)絡(luò)的方式就像是容器直接插入到同一個(gè)網(wǎng)絡(luò)交換機(jī)上,不需要配置端口映射和連接。Weave網(wǎng)絡(luò)上的應(yīng)用容器提供的服務(wù)可以直接在公共網(wǎng)絡(luò)上訪問(wèn),無(wú)論這些容器在哪里運(yùn)行。同樣的,無(wú)論位置在哪,現(xiàn)有的內(nèi)部系統(tǒng)都是暴露給應(yīng)用容器的。Weave可以穿越防火墻,在部分連接的網(wǎng)絡(luò)中運(yùn)行。流量可以加密,允許主機(jī)跨越非授信網(wǎng)絡(luò)進(jìn)行連接。你可以從Alvaro Saurin的文章Automating Weave Deployment on Docker Hosts with Weave Discovery中學(xué)習(xí)到Weave的更多特性。
?
?
Project Calico
Metaswitch的Calico項(xiàng)目使用標(biāo)準(zhǔn)IP路由,嚴(yán)格的說(shuō)是RFC 1105中定義的邊界網(wǎng)關(guān)協(xié)議(Border Gateway Protocol,簡(jiǎn)稱BGP),并能使用網(wǎng)絡(luò)工具提供3層解決方案。相反,大多數(shù)其他的網(wǎng)絡(luò)解決方案(包括Weave)是通過(guò)封裝2層流量到更高層來(lái)構(gòu)建一個(gè)overlay網(wǎng)絡(luò)。主操作模式不需要任何封裝,是為可以控制物理網(wǎng)絡(luò)結(jié)構(gòu)的組織的數(shù)據(jù)中心設(shè)計(jì)的。
?
?
Open vSwitch
Open vSwitch是一個(gè)多層虛擬交換機(jī),通過(guò)可編程擴(kuò)展來(lái)實(shí)現(xiàn)網(wǎng)絡(luò)自動(dòng)化,支持標(biāo)準(zhǔn)管理接口和協(xié)議,如NetFlow、IPFIX、LACP和802.1ag。除此之外,它還支持在多個(gè)物理服務(wù)器上分發(fā),和VMware的vNetwork distributed vSwitch、Cisco的Nexus 1000V類似。
?
?
Pipework
Pipework由著名的Docker工程師Jér?me Petazzoni創(chuàng)建,稱為L(zhǎng)inux容器的軟件定義網(wǎng)絡(luò)。它允許你使用cgroups和namespace在任意復(fù)雜的場(chǎng)景中連接容器,并與LXC容器或者Docker兼容。由于Docker, Inc.收購(gòu)了SocketPlane并引入了Overlay Driver,我們必須看一下這些技術(shù)如何融合。
?
?
OpenVPN
OpenVPN,另一個(gè)有商業(yè)版本的開源項(xiàng)目,運(yùn)行你創(chuàng)建使用TLS的虛擬私有網(wǎng)絡(luò)(virtual private networks,簡(jiǎn)稱VPN)。這些VPN也可以安全地跨越公共網(wǎng)絡(luò)連接容器。如果你想嘗試一下基于Docker的配置,我建議看一下DigitalOcean很贊的教程How To Run OpenVPN in a Docker Container on Ubuntu 14.04。
?
?
未來(lái)的Docker網(wǎng)絡(luò)
在最近發(fā)布的Docker v1.9中,引入了一個(gè)新的命令docker network。容器可以動(dòng)態(tài)地連接到其他網(wǎng)絡(luò)上,每個(gè)網(wǎng)絡(luò)都可以由不同的網(wǎng)絡(luò)驅(qū)動(dòng)來(lái)支持。默認(rèn)的多主機(jī)網(wǎng)絡(luò)驅(qū)動(dòng)是Overlay。
為了了解更多實(shí)踐經(jīng)驗(yàn),我建議看一下以下博客:
?
?
- Aleksandr Tarasov的Splendors and Miseries of Docker Network
- Calico項(xiàng)目的Docker libnetwork Is Almost Here, and Calico Is Ready!
- Weave Works的Life and Docker Networking – One Year On
?
?
更多話題
在本章中,我們討論了多主機(jī)網(wǎng)絡(luò)中的各種解決方案。這一小節(jié)會(huì)簡(jiǎn)要介紹一下其他需要了解的話題:
?
?
IPVLAN
Linux內(nèi)核v3.19引入了每個(gè)容器一個(gè)IP地址的特性,它分配給主機(jī)上的每個(gè)容器一個(gè)唯一的、可路由的IP地址。實(shí)際上,IPVLAN使用一個(gè)網(wǎng)卡接口,創(chuàng)建了多個(gè)虛擬的網(wǎng)卡接口,并分配了不同的MAC地址。這個(gè)相對(duì)較新的特性是由Google的Mahesh Bandewar貢獻(xiàn)的,與macvlan驅(qū)動(dòng)類似,但是更加靈活,因?yàn)樗梢酝瑫r(shí)使用在L2和L3上。如果你的Linux發(fā)行版已經(jīng)使用了高于3.19的內(nèi)核,那么你很幸運(yùn);否則,你就無(wú)法享受這個(gè)新功能。
?
IP地址管理(IPAM)
多主機(jī)網(wǎng)絡(luò)中,最大的挑戰(zhàn)之一就是集群中容器的IP地址分配。
?
編排工具兼容性
本章中討論的大多數(shù)多主機(jī)網(wǎng)絡(luò)解決方案都是封裝了Docker API,并配置網(wǎng)絡(luò)。也就是說(shuō),在你選擇其中一個(gè)之前,你需要檢查與容器編排工具的可兼容性。更多主題,請(qǐng)看第5章。
?
IPv4 vs. IPv6
到目前為止,大多數(shù)Docker部署使用的是標(biāo)準(zhǔn)IPv4,但是IPv6正在迎頭趕上。Docker從v1.5(2015年2月發(fā)布)開始支持IPv6。IPv4的持續(xù)減少將會(huì)導(dǎo)致越來(lái)越多的IPv6部署,也可以擺脫NATs。然而,什么時(shí)候轉(zhuǎn)變完成還不清楚。
現(xiàn)在,你已經(jīng)對(duì)底層網(wǎng)絡(luò)和Docker網(wǎng)絡(luò)的解決方案有了充分理解,讓我們進(jìn)入下一個(gè)內(nèi)容:服務(wù)發(fā)現(xiàn)。
?
容器和服務(wù)發(fā)現(xiàn)
管理基礎(chǔ)架構(gòu)的cattle方法的最大挑戰(zhàn)就是服務(wù)發(fā)現(xiàn)。服務(wù)發(fā)現(xiàn)和容器調(diào)度是一枚硬幣的兩面。如果你使用cattle方法的話,那么你會(huì)把所有機(jī)器看做相同的,你不會(huì)手動(dòng)分配某臺(tái)機(jī)器給某個(gè)應(yīng)用。相反,你會(huì)使用調(diào)度軟件來(lái)管理容器的生命周期。
那么,問(wèn)題就來(lái)了:如何決定容器被調(diào)度到哪臺(tái)宿主機(jī)上?答對(duì)了,這就是服務(wù)發(fā)現(xiàn)。我們會(huì)在第5章詳細(xì)討論硬幣的另一面:容器編排。
?
?
挑戰(zhàn)
服務(wù)發(fā)現(xiàn)已經(jīng)出現(xiàn)了一段時(shí)間了,被認(rèn)為是zeroconf的一部分。
zeroconf
zeroconf的想法是自動(dòng)化創(chuàng)建和管理計(jì)算機(jī)網(wǎng)絡(luò),自動(dòng)分配網(wǎng)絡(luò)地址,自動(dòng)分發(fā)和解析主機(jī)名,自動(dòng)管理網(wǎng)絡(luò)服務(wù)。
對(duì)于Docker容器來(lái)說(shuō),這個(gè)挑戰(zhàn)歸結(jié)于穩(wěn)定地維護(hù)運(yùn)行中容器和位置(location)的映射關(guān)系。位置這里指的是IP地址(啟動(dòng)容器的宿主機(jī)地址)和可被訪問(wèn)的端口。這個(gè)映射必須及時(shí)完成,并在集群中準(zhǔn)確地重啟容器。容器的服務(wù)發(fā)現(xiàn)解決方案必須支持以下兩個(gè)操作:
?
?
注冊(cè)(Register)
建立container->location的映射。因?yàn)橹挥腥萜髡{(diào)度器才知道容器運(yùn)行在哪,我們可以把該映射當(dāng)做容器位置的“絕對(duì)真理”(the absolute source of truth)。
?
查詢(Lookup)
其他服務(wù)或應(yīng)用可以查詢我們存儲(chǔ)的映射關(guān)系,屬性包括信息的實(shí)時(shí)性和查詢延遲。
讓我們看一下在選擇過(guò)程中相對(duì)獨(dú)立的幾點(diǎn)考慮:
?
- 除了簡(jiǎn)單地向一個(gè)特定方向發(fā)送請(qǐng)求之外,怎么從搜索路徑中排除不健康的宿主機(jī)和掛掉的容器?你已經(jīng)猜到了,這是和負(fù)載均衡高度相關(guān)的主題,因?yàn)檫@是很重要的,所以本章的最后一小節(jié)將討論這一主題。
- 有人認(rèn)為這是實(shí)現(xiàn)細(xì)節(jié),也有人認(rèn)為需要考慮CAP三要素。在選擇服務(wù)發(fā)現(xiàn)工具時(shí),需要考慮選擇強(qiáng)一致性(strong consistency)還是高可用性(high availability)。至少你要意識(shí)到這一點(diǎn)。
- 可擴(kuò)展性也會(huì)影響你的選擇。當(dāng)然,如果你只有少量的節(jié)點(diǎn)需要管理,那么上面討論的解決方案就夠用了。然而,如果你的集群有100多個(gè)節(jié)點(diǎn),甚至1000個(gè)節(jié)點(diǎn),那么在選擇某一項(xiàng)特定技術(shù)之前,你必須做一些負(fù)載測(cè)試。
?
?
CAP理論1998年,Eric Brewer提出了分布式系統(tǒng)的CAP理論。CAP代表了一致性(consistency)、可用性(availability)和分區(qū)容錯(cuò)性(partition tolerance):?
一致性
分布式系統(tǒng)的所有節(jié)點(diǎn)同時(shí)看到相同的數(shù)據(jù)。?
可用性
保證每個(gè)請(qǐng)求都能得到響應(yīng),無(wú)論該響應(yīng)是成功還是失敗。
分區(qū)容錯(cuò)性?
無(wú)論哪塊分區(qū)由于網(wǎng)絡(luò)故障而失效,分布式系統(tǒng)都可以繼續(xù)運(yùn)行。
CAP理論在分布式系統(tǒng)的實(shí)踐中已經(jīng)討論多次了。你會(huì)聽(tīng)到人們主要討論強(qiáng)一致性 vs 最終一致性,我建議讀一下Martin Kleppmann的論文A Critique of the CAP Theorem。該論文提出了一種不同的、更實(shí)際的思考CAP的方法,特別是一致性。
如果你想了解該領(lǐng)域更多的需求和根本的挑戰(zhàn),可以讀一下Jeff Lindsay的Understanding Modern Service Discovery with Docker和Shopify的Simon Eskildsen在DockerCon分享的內(nèi)容。
?
?
技術(shù)
該小節(jié)介紹了各種技術(shù)和它們的優(yōu)缺點(diǎn),并提供了網(wǎng)上的更多資源(如果你想獲得這些技術(shù)的實(shí)踐經(jīng)驗(yàn),你可以看看Adrian Mouat的書Using Docker)。
?
?
ZooKeeper
Apache?ZooKeeper是ASF的頂級(jí)項(xiàng)目,基于JVM的集中式配置管理工具,提供了與Google的Chubby相兼容的功能。ZooKeeper(ZK)將數(shù)據(jù)載荷組織成文件系統(tǒng),成為znodes的層級(jí)結(jié)構(gòu)。在集群中,選舉出一個(gè)leader節(jié)點(diǎn),客戶端能夠連接到服務(wù)器中的任意一個(gè)來(lái)獲取數(shù)據(jù)。一個(gè)ZK集群中需要2n+1個(gè)節(jié)點(diǎn)。最常見(jiàn)的配置是3、5、7個(gè)節(jié)點(diǎn)。
ZooKeeper是經(jīng)戰(zhàn)場(chǎng)證明的、成熟的、可擴(kuò)展的解決方案,但是也有一下缺點(diǎn)。有些人認(rèn)為ZK集群的安裝和管理不是一個(gè)令人愉快的體驗(yàn)。我碰到的大多數(shù)ZK問(wèn)題都是因?yàn)槟硞€(gè)服務(wù)(我想到了Apache Storm)錯(cuò)誤地使用了它。它們可能在znodes里放入了太多數(shù)據(jù),更糟糕的是,他們的讀寫率很不健康(unhealthy read-write ratio),特別是寫得太快。如果你打算使用ZK的話,至少考慮使用高層接口。例如,Apache Curator封裝了ZK,提供了大量的方法;Netflix的Exhibitor可以管理和監(jiān)控一個(gè)ZK集群。
從圖4-1可以看出,你可以看到兩個(gè)組件:R/W(作為注冊(cè)監(jiān)控器(registration watcher),你需要自己提供)和NGINX(被R/W控制)。當(dāng)一個(gè)容器被調(diào)度到一個(gè)節(jié)點(diǎn)上時(shí),它會(huì)在ZK中注冊(cè),使用一個(gè)路徑為/$nodeID/$containerID的znode,IP地址作為數(shù)據(jù)載荷。R/W監(jiān)控znodes節(jié)點(diǎn)的變化,然后相應(yīng)地配置NGINX。這種方法對(duì)于HAProxy和其他負(fù)載均衡器也同樣有效。
?
圖 4-1
?
etcd
etcd是由CoreOS團(tuán)隊(duì)使用Go語(yǔ)言編寫的。它是一個(gè)輕量級(jí)的、分布式鍵值對(duì)數(shù)據(jù)庫(kù),使用Raft算法實(shí)現(xiàn)一致性(帶有l(wèi)eader選舉的leader-follower模型),在集群中使用復(fù)制日志(replicated log)向followers分發(fā)lead收到的寫請(qǐng)求。從某種意義上說(shuō),在概念上,etcd和ZK是相當(dāng)類似的。雖然負(fù)載數(shù)據(jù)是任意的,但是etcd的HTTP API是基于JSON的。就像ZK一樣,你可以觀察到etcd保存的值的變化。etcd的一個(gè)非常有用的特性是鍵的TTL,是服務(wù)發(fā)現(xiàn)的重要的一個(gè)結(jié)構(gòu)單元。和ZK一樣,一個(gè)etcd集群至少需要2n+1個(gè)節(jié)點(diǎn)。
etcd的安全模型支持基于TLS/SSL和客戶端證書加密的線上加密(on-the-wire encryption),加密可以發(fā)生在客戶端和集群之間,也可以在etcd節(jié)點(diǎn)之間。
在圖4-2中,你可以看到etcd服務(wù)發(fā)現(xiàn)的搭建和ZK是相當(dāng)類似的。主要區(qū)別在于etcd使用confd來(lái)配置NGINX,而不是使用自己編寫的腳本。和ZK一樣,這種搭建方法也適用于HAProxy或者其他負(fù)載均衡器。
?
圖 4-2
?
Consul
Consul是HashiCorp的產(chǎn)品,也是用Go語(yǔ)言寫的,功能有服務(wù)注冊(cè)、服務(wù)發(fā)現(xiàn)和健康檢查,可以使用HTTP API或者DNS來(lái)查詢服務(wù)。Consul支持多數(shù)據(jù)中心的部署。
Consul的其中一個(gè)特性是一個(gè)分布式鍵值對(duì)數(shù)據(jù)庫(kù),與etcd相似。它也是用Raft一致性算法(同樣需要2n+1個(gè)節(jié)點(diǎn)),但是部署方式是不同的。Consul有agent的概念,有兩種運(yùn)行方式:服務(wù)器模式(提供鍵值對(duì)數(shù)據(jù)庫(kù)和DNS)和客戶端模式(注冊(cè)服務(wù)和健康檢查),使用serf實(shí)現(xiàn)了成員和節(jié)點(diǎn)發(fā)現(xiàn)。
使用Consul,你有四種方式來(lái)實(shí)現(xiàn)服務(wù)發(fā)現(xiàn)(從最可取到最不可取):
?
- 使用服務(wù)定義配置文件(service definition config file),由Consul agent解釋。
- 使用traefik等工具,其中有Consul后端(backend)。
- 編寫你自己的進(jìn)程通過(guò)HTTP API注冊(cè)服務(wù)。
- 讓服務(wù)自己使用HTTP API來(lái)注冊(cè)服務(wù)。
想要學(xué)習(xí)Consul來(lái)做服務(wù)發(fā)現(xiàn)嗎?請(qǐng)閱讀這兩篇文章:Consul Service Discovery with Docker和Docker DNS & Service Discovery with Consul and Registrator。?
?
?
純基于DNS的解決方案
在互聯(lián)網(wǎng)中,DNS經(jīng)受了數(shù)十年的戰(zhàn)場(chǎng)驗(yàn)證,是很健壯的。DNS系統(tǒng)的最終一致性、特定的客戶端強(qiáng)制性地(aggressively)緩存DNS查詢結(jié)果、對(duì)于SRV記錄的依賴這些因素使你明白這是正確的選擇。
本小節(jié)之所以叫做“純基于DNS的解決方案”的原因是,技術(shù)上講Consul也是用了DNS服務(wù)器,但這只是Consul做服務(wù)發(fā)現(xiàn)的其中一個(gè)選項(xiàng)。以下是著名的、常用的、純粹的基于DNS的服務(wù)發(fā)現(xiàn)解決方案:
?
?
Mesos-DNS
該解決方案是專門用于Apache Mesos的服務(wù)發(fā)現(xiàn)的。使用Go編寫,Mesos-DNS下拉任意任務(wù)的有效的Mesos Master進(jìn)程,并通過(guò)DNS或HTTP API暴露IP:PORT信息。對(duì)于其他主機(jī)名或服務(wù)的DNS請(qǐng)求,Mesos-DNS可以使用一個(gè)外部的域名服務(wù)器或者你的現(xiàn)有DNS服務(wù)器來(lái)轉(zhuǎn)發(fā)Mesos任務(wù)的請(qǐng)求到Mesos-DNS。
?
SkyDNS
使用etcd,你可以將你的服務(wù)通告給SkyDNS,SkyDNS在etcd中保存了服務(wù)定義,并更新DNS記錄。你的客戶端應(yīng)用發(fā)送DNS請(qǐng)求來(lái)發(fā)現(xiàn)服務(wù)。因此,在功能層面,SkyDNS與Consul是相當(dāng)類似的,只是沒(méi)有健康檢查。
?
WeaveDNS
WeaveDNS由Weave 0.9引入,作為Weave網(wǎng)絡(luò)的服務(wù)發(fā)現(xiàn)解決方案,允許容器按照主機(jī)名找到其他容器的IP地址。在Weave 1.1中,引入了所謂的Gossip DNS,通過(guò)緩存和超時(shí)功能使得查詢更加快速。在最新的實(shí)現(xiàn)中,注冊(cè)是廣播到所有參與的實(shí)例上,在內(nèi)存中保存所有條目,并在本地處理查詢。
?
Airbnb的SmartStack和Netflix的Eureka
在本小節(jié)中,我們將會(huì)看一下兩個(gè)定做的系統(tǒng),它們是用來(lái)解決特定的需求。這并不意味著你不能或者不應(yīng)該使用它們,你只是需要意識(shí)到它們。
Airbnb的SmartStack是一個(gè)自動(dòng)的服務(wù)發(fā)現(xiàn)和注冊(cè)框架,透明地處理創(chuàng)建、刪除、故障和維護(hù)工作。在容器運(yùn)行的同一個(gè)宿主機(jī)上,SmartStack使用了兩個(gè)分離的服務(wù):Nerve(寫到ZK)用于服務(wù)注冊(cè),Synapse(動(dòng)態(tài)配置HAProxy)用于查詢。這是一個(gè)針對(duì)非容器環(huán)境的完善的解決方案,隨著實(shí)踐推移,你會(huì)看到對(duì)于Docker,SmartStack也是有用的。
Netflix的Eureka則不同,它運(yùn)行在AWS環(huán)境中(Netflix全部運(yùn)行在AWS上)。Eureka是一個(gè)基于REST的服務(wù),用于定位服務(wù)以便負(fù)載均衡和中間件層服務(wù)器的故障遷移;Eureka還有一個(gè)基于Java的客戶端組件,可以直接與服務(wù)交互。這個(gè)客戶端有一個(gè)內(nèi)置的負(fù)載均衡器,可以做基本的round-robin的負(fù)載均衡。在Netflix,Eureka用于做red/black部署、Cassandra和memcached部署、承載應(yīng)用中關(guān)于服務(wù)的元數(shù)據(jù)。
Eureka集群在參與的節(jié)點(diǎn)之間異步地復(fù)制服務(wù)注冊(cè)信息;與ZK、etcd、Consul不同,Eureka相對(duì)于強(qiáng)一致性更傾向于服務(wù)可用性,讓客戶端自行處理過(guò)時(shí)的讀請(qǐng)求,優(yōu)點(diǎn)是在網(wǎng)絡(luò)分區(qū)上更有彈性。你也知道的:網(wǎng)絡(luò)是不可靠的。
?
負(fù)載均衡
服務(wù)發(fā)現(xiàn)的一個(gè)方面是負(fù)載均衡,有的時(shí)候負(fù)載均衡被認(rèn)為是正交的,有的時(shí)候負(fù)載均衡被認(rèn)為是服務(wù)發(fā)現(xiàn)的一部分。它可以在很多容器之間分散負(fù)載(入站服務(wù)請(qǐng)求)。在容器和微服務(wù)的語(yǔ)境下,負(fù)載均衡同時(shí)具有以下功能:
?
?
- 最大化吞吐量,最小化響應(yīng)時(shí)間
- 防止熱點(diǎn)(hotspotting),例如單一容器過(guò)載
- 可以處理過(guò)度激進(jìn)的DNS緩存(overly aggressive DNS caching)
以下列舉了一些有名的Docker中的負(fù)載均衡解決方案:
*?NGINX
*?HAProxy
*?Bamboo
*?Kube-Proxy
*?vulcand
*?Magnetic.io的vamp-router
*?moxy
*?HAProxy-SRV
*?Marathon的servicerouter.py
*?traefik
如果你想了解更多關(guān)于負(fù)載均衡的信息,請(qǐng)查看Mesos meetup視頻和nginx.conf 2014上關(guān)于NGINX和Consul的負(fù)載均衡的演講。
?
?
更多話題
在本章的最后,我列舉了服務(wù)發(fā)現(xiàn)解決方案的一覽表。我并不想評(píng)出一個(gè)優(yōu)勝者,因?yàn)槲蚁嘈胚@取決于你的用例和需求。因此,把下表當(dāng)做一個(gè)快速定位和小結(jié):
?
?
最后請(qǐng)注意:服務(wù)發(fā)現(xiàn)領(lǐng)域在不斷變化中,每周都會(huì)出現(xiàn)新工具。例如,Uber最近開源了它的內(nèi)部解決方案Hyperbahn,一個(gè)路由器的overlay網(wǎng)絡(luò),用來(lái)支持TChannel RPC協(xié)議。因?yàn)槿萜鞣?wù)發(fā)現(xiàn)在不斷發(fā)展,因此你可能要重新評(píng)估最初的選擇,直到穩(wěn)定下來(lái)為止。
?
容器和編排
就像上一章中介紹的那樣,使用cattle方法來(lái)管理基礎(chǔ)架構(gòu),你不必手動(dòng)為特定應(yīng)用分配特定機(jī)器。相反,你應(yīng)該使用調(diào)度器來(lái)管理容器的生命周期。盡管調(diào)度是一個(gè)重要的活動(dòng),但是它其實(shí)只是另一個(gè)更廣闊的概念——編排的一部分。
從圖5-1,可以看到編排包括健康檢查(health checks)、組織原語(yǔ)(organizational primitives,如Kubernetes中的labels、Marathon中的groups)、自動(dòng)擴(kuò)展(autoscaling)、升級(jí)/回滾策略、服務(wù)發(fā)現(xiàn)。有時(shí)候base provisioning也被認(rèn)為是編排的一部分,但是這已經(jīng)超出了本書的討論范圍,例如安裝Mesos Agent或Kubernetes Kubelet。
服務(wù)發(fā)現(xiàn)和調(diào)度是同一枚硬幣的兩面。決定一個(gè)特定的容器運(yùn)行在集群的哪個(gè)節(jié)點(diǎn)的實(shí)體,稱之為調(diào)度器。它向其他系統(tǒng)提供了containers->locations的映射關(guān)系,可以以各種方式暴露這些信息,例如像etcd那樣的分布式鍵值對(duì)數(shù)據(jù)庫(kù)、像Mesos-DNS那樣的DNS。
?
?
圖 5-1
本章將從容器編排解決方案的角度討論服務(wù)發(fā)現(xiàn)和網(wǎng)絡(luò)。背后的動(dòng)機(jī)很簡(jiǎn)單:假設(shè)你使用了某個(gè)平臺(tái),如Kubernetes;然后,你主要的關(guān)注點(diǎn)是平臺(tái)如何處理服務(wù)發(fā)現(xiàn)和網(wǎng)絡(luò)。
?
?
注意:接下來(lái),我會(huì)討論滿足以下兩個(gè)條件的容器編排系統(tǒng):開源的和相當(dāng)大的社區(qū)。
你可以看一下以下幾個(gè)不同的解決方案:Fackebook的Bistro或者托管的解決方案,如Amazon EC2的容器服務(wù)ECS。
另外,你如果想多了解一下分布式系統(tǒng)調(diào)度這個(gè)主題,我推薦閱讀Google關(guān)于Borg和Omega的研究論文。
在我們深入探討容器編排系統(tǒng)之前,讓我們先看一下編排的核心組件——調(diào)度器到底是做什么的。
?
?
?
調(diào)度器到底是做什么的?
分布式系統(tǒng)調(diào)度器根據(jù)用戶請(qǐng)求將應(yīng)用分發(fā)到一個(gè)或多個(gè)可用的機(jī)器上。例如,用戶可能請(qǐng)求運(yùn)行應(yīng)用的100個(gè)實(shí)例(或者Kubernetes中的replica)。
在Docker中,這意味著:(a)相應(yīng)的Docker鏡像存在宿主機(jī)上;(b)調(diào)度器告訴本地的Docker Daemon基于該鏡像開啟一個(gè)容器。
在圖5-2中,你可以看到,對(duì)于集群中運(yùn)行的應(yīng)用,用戶請(qǐng)求了三個(gè)實(shí)例。調(diào)度器根據(jù)它對(duì)于集群狀態(tài)的了解,決定將應(yīng)用部署在哪里。比如,機(jī)器的使用情況、成功啟動(dòng)應(yīng)用所必須的資源、約束條件(該應(yīng)用只能運(yùn)行在使用SSD的機(jī)器)等。進(jìn)一步地,服務(wù)質(zhì)量也是考量因素之一。
?
?
圖 5-2
通過(guò)John Wilkes的Cluster Management at Google了解更多內(nèi)容。
?
?
警告:對(duì)于調(diào)度容器的限制條件的語(yǔ)義,你要有概念。例如,有一次我做了一個(gè)Marathon的demo,沒(méi)有按照預(yù)期工作,原因是我沒(méi)有考慮布局的限制條件:我使用了唯一的主機(jī)名和一個(gè)特定的角色這一對(duì)組合。它不能擴(kuò)展,原因是集群中只有一個(gè)節(jié)點(diǎn)符合條件。同樣的問(wèn)題也可能發(fā)生在Kubernetes的label上。
?
?
Vanilla Docker and Docker Swarm
創(chuàng)造性地,Docker提供了一種基本的服務(wù)發(fā)現(xiàn)機(jī)制:Docker連接(links)。默認(rèn)情況下,所有容器都可以相互通信,如果它們知道對(duì)方的IP地址。連接允許用戶任何容器發(fā)現(xiàn)彼此的IP地址,并暴露端口給同一宿主機(jī)上的其他容器。Docker提供了一個(gè)方便的命令行選項(xiàng)--link,可以自動(dòng)實(shí)現(xiàn)這一點(diǎn)。
但是,容器之間的硬連接(hard-wiring of links)并不有趣,也不具擴(kuò)展性。事實(shí)上,這種方法并不算好。長(zhǎng)久來(lái)說(shuō),這個(gè)特性會(huì)被棄用。
讓我們看一下更好的解決方案(如果你仍然想要或者必須使用連接的話):ambassador模式。
?
Ambassadors
如圖5-3所示,這個(gè)模式背后的想法是使用一個(gè)代理容器來(lái)代替真正的容器,并轉(zhuǎn)發(fā)流量。它帶來(lái)的好處是:ambassador模式允許你在開發(fā)階段和生產(chǎn)階段使用不同的網(wǎng)絡(luò)架構(gòu)。網(wǎng)絡(luò)運(yùn)維人員可以在運(yùn)行時(shí)重寫應(yīng)用,而不需要更改應(yīng)用代碼。
簡(jiǎn)單來(lái)說(shuō),ambassador模式的缺點(diǎn)是它不能有效地?cái)U(kuò)展。ambassador模式可以用在小規(guī)模的、手動(dòng)的部署中,但是當(dāng)你使用真正的容器編排工具(如Kubernetes或Apache Mesos)時(shí),應(yīng)該避免使用ambassador模式。
?
?
圖 5-3
?
?
注意:如果你想要了解如何在Docker中部署ambassador模式,我再次建議你參考Adrian Mouat的書Using Docker。事實(shí)上,在圖5-3中,我使用的就是他的amouat/ambassador鏡像。
?
?
Docker Swarm
除了容器的靜態(tài)鏈接(static linking),Docker有一個(gè)原生的集群工具Docker Swarm。Docker Swarm基于Docker API構(gòu)建,并通過(guò)以下方式工作:有一個(gè)Swarm manager負(fù)載調(diào)度,在每一個(gè)宿主機(jī)上運(yùn)行了一個(gè)agent,負(fù)責(zé)本地資源管理(如圖5-4所示)。
Swarm中有趣的地方在于,調(diào)度器是插件式的(plug-able),所以你可以使用除了內(nèi)置以外的其他調(diào)度器,如Apache Mesos。在寫本書的過(guò)程中,Swarm發(fā)布了1.0版本,并完成了GA(General Availability);新的特性(如高可用性)正在進(jìn)行開發(fā)中。
?
圖 5-4
?
網(wǎng)絡(luò)
在本書的第2章和第3章中,我們介紹了Docker中的單宿主機(jī)和多宿主機(jī)中的網(wǎng)絡(luò)。
?
服務(wù)發(fā)現(xiàn)
Docker Swarm支持不同的后端:etcd、Consul和Zookeeper。你也可以使用靜態(tài)文件來(lái)捕捉集群狀態(tài)。最近,一個(gè)基于DNS的服務(wù)發(fā)現(xiàn)工具wagl被引入到了Swarm中。
如果你想更多了解Docker Swarm,可以讀一下Rajdeep Dua的幻燈片。
?
Kubernetes
Kubernetes(請(qǐng)看圖5-5)是一個(gè)opinionated的開源框架,彈性地管理容器化的應(yīng)用。簡(jiǎn)單來(lái)說(shuō),它吸取了Google超過(guò)十年的運(yùn)行容器負(fù)載的經(jīng)驗(yàn),我們會(huì)簡(jiǎn)要地介紹一下。進(jìn)一步地,你總是可以選擇其他開源或閉源的方法來(lái)替換Kubernetes的默認(rèn)實(shí)現(xiàn),比如DNS或監(jiān)控。
?
?
圖 5-5
以下討論假設(shè)你已經(jīng)熟悉Kubernetes和它的技術(shù)。如果你還不熟悉Kubernetes的話,我建議看一下Kelsey HighTower的Kubernetes Up and Running。
Kubernetes中,調(diào)度單元是一個(gè)pod,這是a tightly coupled set of containers that is always collocated。pod運(yùn)行實(shí)例的數(shù)目是由Replication Controller定義和指定的。pods和services的邏輯組織是由labels定義的。
在每個(gè)Kubernetes節(jié)點(diǎn)上,運(yùn)行著一個(gè)稱為Kubelet的agent,負(fù)責(zé)控制Docker daemon,向Master匯報(bào)節(jié)點(diǎn)狀態(tài),設(shè)置節(jié)點(diǎn)資源。Master節(jié)點(diǎn)提供API(例如,圖5-6中的web UI),收集集群現(xiàn)在的狀態(tài),并存儲(chǔ)在etcd中,將pods調(diào)度到節(jié)點(diǎn)上。
?
圖 5-6
?
網(wǎng)絡(luò)
在Kubernetes中,每個(gè)pod都有一個(gè)可路由的IP,不需要NAT,集群節(jié)點(diǎn)上的pods之間也可以相互通信。pod中的所有容器共享一個(gè)端口命名空間(port namespace)和同一個(gè)notion localhost,因此沒(méi)有必要做端口代理(port brokering)。這是Kubernetes的基本要求,可以通過(guò)network overlay來(lái)實(shí)現(xiàn)。
在pod中,存在一個(gè)所謂的infrastructure容器,kubelet實(shí)例化的第一個(gè)容器,它會(huì)獲得pod的IP,并設(shè)置網(wǎng)絡(luò)命名空間。pod中的所有其他容器會(huì)加入到infra容器的網(wǎng)絡(luò)和IPC命名空間。infra容器的網(wǎng)絡(luò)啟用了bridge模式(請(qǐng)參考第九頁(yè)的bridge模式網(wǎng)絡(luò)),pod中的所有其他容器使用container模式(請(qǐng)參考第11頁(yè)的container模式網(wǎng)絡(luò))來(lái)共享它的命名空間。infra容器中的初始進(jìn)程實(shí)際上什么也沒(méi)做,因?yàn)樗哪康闹皇翘峁┟臻g的載體。關(guān)于端口轉(zhuǎn)發(fā)的最近的work around可能在infra容器中啟動(dòng)額外的進(jìn)程。如果infra容器死亡的話,那么Kubelet會(huì)殺死pod中所有的進(jìn)程,然后重新啟動(dòng)進(jìn)程。
進(jìn)一步地,Kubernetes的命名空間會(huì)啟動(dòng)所有control points。其中一個(gè)網(wǎng)絡(luò)命名空間的例子是,Calico項(xiàng)目使用命名空間來(lái)強(qiáng)化coarse-grained網(wǎng)絡(luò)策略(policy)。
?
服務(wù)發(fā)現(xiàn)
在Kubernetes的世界里,有一個(gè)服務(wù)發(fā)現(xiàn)的canonical抽象,這是service primitive。盡管pods隨時(shí)可能啟動(dòng)和銷毀因?yàn)樗麄兛赡苁?#xff08;或者pods運(yùn)行的宿主機(jī)失敗),服務(wù)是長(zhǎng)時(shí)間運(yùn)行的:它們提供集群層面的服務(wù)發(fā)現(xiàn)和某種級(jí)別的負(fù)載均衡。它們提供了一個(gè)穩(wěn)定的IP地址和持久化名字,compensating for the shortlivedness of all equally labelled pods。Kubernetes提供了兩種發(fā)現(xiàn)機(jī)制:通過(guò)環(huán)境變量(限制于一個(gè)特定節(jié)點(diǎn)上)和DNS(集群層面上的)。
?
Apache Mesos
Apache Mesos?(圖5-7)是一個(gè)通用的集群資源管理器,抽象了集群中的各項(xiàng)資源(CPU、RAM等),通過(guò)這種方式,集群對(duì)于開發(fā)者來(lái)說(shuō)就像一個(gè)巨大的計(jì)算機(jī)。
在某種程度上,Mesos可以看作是分布式操作系統(tǒng)的內(nèi)核。因此,它從未單獨(dú)使用,總是和其他框架一起工作,例如Marathon(用于long-running任務(wù),如web服務(wù)器)、Chronos(用于批量任務(wù))或者大數(shù)據(jù)框架(如Apache Spark或Apache Cassandra)。
?
?
圖 5-7
Mesos同時(shí)支持容器化負(fù)載(Docker容器)和普通的可執(zhí)行文件(包括bash腳本、Python腳本、基于JVM的應(yīng)用、一個(gè)純粹的老的Linux二進(jìn)制格式),也支持無(wú)狀態(tài)和有狀態(tài)的服務(wù)。
接下來(lái),我假設(shè)你已經(jīng)熟悉了Mesos和它的相關(guān)技術(shù)。如果你不熟悉Mesos,我建議你閱讀David Greenberg的書《Building Applications on Mesos》,該書介紹了Mesos,特別是對(duì)于分布式應(yīng)用的開發(fā)者。
如圖5-8所示,你可以看到Marathon的UI,使用Apache Mesos來(lái)啟動(dòng)和管理長(zhǎng)期運(yùn)行的服務(wù)和應(yīng)用。
?
圖 5-8
?
網(wǎng)絡(luò)
網(wǎng)絡(luò)特性和能力主要取決于Mesos使用的容器方案:
?
- 對(duì)于Mesos containerizer來(lái)說(shuō),有一些要求,如Linux內(nèi)核版本要大于3.16,并安裝libnl。開啟網(wǎng)絡(luò)隔離功能之后,你可以構(gòu)建一個(gè)Mesos Agent。啟動(dòng)之后,你可以看到以下輸出:
? mesos-slave?--containerizer=mesos?--isolation=network/port_mapping?--resources=ports:[31000-32000];ephemeral_ports:?[33000-35000]
Mesos Agent會(huì)配置成使用非臨時(shí)(non-ephemeral)端口31000-32000,臨時(shí)(ephemeral)端口33000-35000。所有容器共享宿主機(jī)的IP地址,端口范圍被分配到各個(gè)容器上(使用目的端口和容器ID之間的1:1映射)。通過(guò)網(wǎng)絡(luò)隔離,你可以定義網(wǎng)絡(luò)性能(如帶寬),使得你能夠監(jiān)控容器的網(wǎng)絡(luò)流量。更多細(xì)節(jié),請(qǐng)看MesosCon 2015 Seattle上的演講Per Container Network Monitoring and Isolation in Mesos。 - 對(duì)于Docker containerizer,請(qǐng)看第二章。
?
?
服務(wù)發(fā)現(xiàn)
盡管Mesos不提供服務(wù)發(fā)現(xiàn)功能,但是有一個(gè)Mesos特定的解決方案,在praxis中也很常用:Mesos-DNS(Pure-Play DNS-based Solutions)。然而,還有其他的解決方案,如traefik。如果你對(duì)于Mesos中的服務(wù)發(fā)現(xiàn)很感興趣,我們的文檔中有一個(gè)專門的章節(jié)介紹它。
?
Hashicorp Nomad
Nomad是HashiCorp開發(fā)的集群調(diào)度器,HashiCorp也開發(fā)了Vagrant。Nomad于2015年9月份引入,主要目的是簡(jiǎn)化性。Nomad易于安裝和使用。據(jù)說(shuō),它的調(diào)度器設(shè)計(jì)受到Google的Omega的影響,比如維護(hù)了集群的全局狀態(tài)、使用優(yōu)化的、高并發(fā)的調(diào)度器。
Nomad的架構(gòu)是基于agent的,它有一個(gè)單獨(dú)的二進(jìn)制文件,可以承擔(dān)不同的角色,支持滾動(dòng)升級(jí)(rolling upgrade)和draining nodes(為了重新平衡)。Nomad使用了一致性協(xié)議(強(qiáng)一致性)來(lái)實(shí)現(xiàn)所有的狀態(tài)復(fù)制和調(diào)度,使用gossip協(xié)議來(lái)管理服務(wù)器地址,從而實(shí)現(xiàn)集群自動(dòng)化(automatic clustering)和多區(qū)域聯(lián)合(multiregion federation)。從圖5-9可以看到,Nomad agent正在啟動(dòng)。
?
?
圖 5-9
Jobs定義為HCL格式(HashiCorp-proprietary format)或JSON格式。Nomad提供了命令行接口和HTTP API,來(lái)和服務(wù)器進(jìn)程進(jìn)行交互。
接下來(lái),我假設(shè)你已經(jīng)熟悉了Nomad和它的術(shù)語(yǔ),否則我不建議你讀這一節(jié)。如果你不熟悉的話,我建議你讀一下Nomad: A Distributed, Optimistically Concurrent Schedule: Armon Dadgar, HashiCorp(這是HashiCorp的CTO Armon Dadgar對(duì)于Nomad的介紹)和Nomad的文檔。
?
網(wǎng)絡(luò)
Nomad中有幾個(gè)所謂的任務(wù)驅(qū)動(dòng)(task drivers),從通用的Java可執(zhí)行程序到qemu和Docker。在之后的討論中,我們將會(huì)專注后者。
在寫這篇文章的時(shí)候,Nomad要求Docker的版本為1.8.2,并使用端口綁定技術(shù),將容器中運(yùn)行的服務(wù)暴露在宿主機(jī)網(wǎng)卡接口的端口空間中。Nomad提供了自動(dòng)的和手動(dòng)的映射方案,綁定Docker容器的TCP和UDP協(xié)議端口。
關(guān)于網(wǎng)絡(luò)選項(xiàng)的更多細(xì)節(jié),例如端口映射(mapping ports)和標(biāo)簽(labels),我建議你讀一下該文章。
?
服務(wù)發(fā)現(xiàn)
在v0.2中,Nomad提供了基于Consul的服務(wù)發(fā)現(xiàn)機(jī)制,請(qǐng)參考相關(guān)文檔。其中包含了健康檢查(health checks),并假設(shè)運(yùn)行在Nomad中的任務(wù)能夠與Consul agent通信(使用bridge模式網(wǎng)絡(luò)),這是一個(gè)挑戰(zhàn)。
?
我應(yīng)該用哪個(gè)呢?
以下內(nèi)容當(dāng)然只是我的一個(gè)建議。這是基于我的經(jīng)驗(yàn),自然地,我也偏向于我正在使用的東西。可能有各種原因(包括政治上的原因)導(dǎo)致你選擇一個(gè)特定的技術(shù)。
從純粹的可擴(kuò)展性的角度來(lái)看,這些選項(xiàng)有以下特點(diǎn):
?
?
對(duì)于少量的節(jié)點(diǎn)來(lái)說(shuō),自然是無(wú)所謂的:根據(jù)你的偏好和經(jīng)驗(yàn),選擇以上四個(gè)選項(xiàng)中的任意一個(gè)都可以。但是請(qǐng)記住,管理大規(guī)模的容器是很困難的:
?
- Docker Swarm可以管理1000個(gè)節(jié)點(diǎn),請(qǐng)參考HackerNews和Docker的這篇博客。
- Kubernetes 1.0據(jù)說(shuō)可以擴(kuò)展至100個(gè)節(jié)點(diǎn),并在持續(xù)改進(jìn)中,以達(dá)到和Apache Mesos同樣的可擴(kuò)展性。
- Apache Mesos可以管理最多50000個(gè)節(jié)點(diǎn)。
- 到目前為止,還沒(méi)有資料表明Nomad可以管理多少個(gè)節(jié)點(diǎn)。
從工作負(fù)載的角度來(lái)看,這些選項(xiàng)有以下特點(diǎn):
?
?
非容器化(Non-containerized)意味著你可以運(yùn)行任何Linux Shell中可以運(yùn)行的程序,例如bash或Python腳本、Java程序等。容器化(containerized)以為你需要生成一個(gè)Docker鏡像。考慮到有狀態(tài)服務(wù),當(dāng)今應(yīng)用中的很大一部分需要一些調(diào)整。如果你想更多地學(xué)習(xí)編排工具,請(qǐng)參考:
?
- Docker Clustering Tools Compared: Kubernetes vs Docker Swarm
- O'Reilly Radar的Swarm v. Fleet v. Kubernetes v. Mesos
為了完整性,我想介紹這個(gè)領(lǐng)域的一個(gè)新成員Firmament,這是一個(gè)非常不錯(cuò)的項(xiàng)目。這個(gè)項(xiàng)目的開發(fā)者們也是Google的Omega和Borg的貢獻(xiàn)者,這個(gè)新的調(diào)度器將任務(wù)和機(jī)器組成了一個(gè)流網(wǎng)絡(luò),并運(yùn)行最小成本優(yōu)化(minimum-cost optimization)。特別有趣的一點(diǎn)是,Firmament不僅可以單獨(dú)使用,也可以與Kubernetes和Mesos整合。
?
?
容器的一天
當(dāng)選擇使用哪種容器編排方案時(shí),你需要考慮容器的整個(gè)生命流程。
?
圖 5-10
Docker容器典型的生命周期包括以下幾個(gè)階段:
?
階段1: dev
容器鏡像(你的服務(wù)和應(yīng)用)從一個(gè)開發(fā)環(huán)境中開始它的生命流程,通常是從一名開發(fā)者的筆記本開始的。你可以使用生產(chǎn)環(huán)境中運(yùn)行的服務(wù)和應(yīng)用的特性請(qǐng)求(feature requests)作為輸入。
?
階段2: CI/CD
然后,容器需要經(jīng)歷持續(xù)集成和持續(xù)發(fā)布(continuous integration and continous delivery),包括單元測(cè)試、整合測(cè)試和冒煙測(cè)試。
?
階段3: QA/staging
然后,你可以使用一個(gè)QA環(huán)境(企業(yè)內(nèi)部或云中的集群)和/或staging階段。
?
階段4:prod
最后,容器鏡像是部署到生產(chǎn)環(huán)境中的。你也需要有一個(gè)策略去分發(fā)這些鏡像。不要忘記以canaries的方式進(jìn)行構(gòu)建,并為核心系統(tǒng)(如Apache Mesos)、潛在的高層組件(如Marathon)和你的服務(wù)和應(yīng)用的滾動(dòng)式升級(jí)(rolling upgrade)做計(jì)劃。
在生產(chǎn)環(huán)境中,你會(huì)發(fā)現(xiàn)bugs,并收集相關(guān)指標(biāo),可以用來(lái)改善下一個(gè)迭代(返回到階段1)。
這里討論的大部分系統(tǒng)(Swarm、Kubernetes、Mesos和Nomad)提供了很多指令、協(xié)議和整合點(diǎn)來(lái)覆蓋這些階段。然而,在你選擇任何一個(gè)系統(tǒng)之前,你仍然需要端到端地試用該系統(tǒng)。
?
社區(qū)是很重要的
當(dāng)選擇編排系統(tǒng)時(shí),另一個(gè)你需要考慮的一件方面是背后的社區(qū)。以下是一些指標(biāo):
?
- 是否由一個(gè)正式的實(shí)體或流程來(lái)管理?例如,Apache軟件基金會(huì)或Linux基金會(huì)。
- 郵件列表、IRC頻道、bug/issue追蹤器、Git倉(cāng)庫(kù)(補(bǔ)丁或PR的數(shù)量)是否活躍?看一下歷史情況,但是請(qǐng)?zhí)貏e注意活躍度。一個(gè)健康的社區(qū)至少會(huì)在其中一個(gè)領(lǐng)域非常活躍。
- 該編排工具是否由一個(gè)單一實(shí)體實(shí)際控制?例如,對(duì)于Nomad來(lái)說(shuō),很明顯的是,HashiCorp具有完全控制權(quán)。那么Kubernetes和Mesos呢?
- 是否有多個(gè)獨(dú)立的提供商提供支持?例如,你可以在多個(gè)不同的環(huán)境中運(yùn)行Kubernetes或Mesos,并從很多商業(yè)或非商業(yè)的組織和個(gè)人得到幫助。
我們已經(jīng)到了本書的結(jié)尾。在容器的網(wǎng)絡(luò)和服務(wù)發(fā)現(xiàn)方面,你已經(jīng)學(xué)習(xí)到了不少知識(shí)。看完本章之后,你已經(jīng)可以選擇和部署容器化應(yīng)用了。如果你希望深入地了解本書中的各個(gè)主體,請(qǐng)查看附錄A,附錄A提供了大量的資源列表。
?
?
?
附錄A 參考
以下這些鏈接,有的包含了背景知識(shí),有的包含了一些高級(jí)內(nèi)容。
?
?
?
網(wǎng)絡(luò)參考
- Docker Networking
- Concerning Containers’ Connections: on Docker Networking
- Unifying Docker Container and VM Networking
- Exploring LXC Networking
- Letting Go: Docker Networking and Knowing When Enough Is Enough
- Networking in Containers and Container Clusters
?
服務(wù)發(fā)現(xiàn)參考
- Service Discovery on?p24e.io
- Understanding Modern Service Discovery with Docker
- Service Discovery in Docker Environments
- Service Discovery, Mesosphere
- Docker Service Discovery Using Etcd and HAProxy
- Service discovery with Docker:?Part 1?and?Part 2
- Service Discovery with Docker: Docker Links and Beyond
?
其他高級(jí)話題
- What Makes a Container Cluster?
- Fail at Scale—Reliability in the Face of Rapid Change
- Bistro: Scheduling Data-Parallel Jobs Against Live Production Systems
- Orchestrating Docker Containers with Slack
- The History of Containers
- The Comparison and Context of Unikernels and Containers
- Anatomy of a Container: Namespaces, cgroups & Some Filesystem Magic - LinuxCon
原文鏈接:Docker networking and service discovery(翻譯:夏彬)
總結(jié)
以上是生活随笔為你收集整理的Docker网络和服务发现的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: Go语言学习之encoding/json
- 下一篇: 从HashiCorp Nomad对上百万