日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

Docker网络和服务发现

發(fā)布時間:2025/3/21 编程问答 48 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Docker网络和服务发现 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

【編者的話】 本文是《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)用的時候,對于Docker的能力和它帶來的機(jī)會,你會感到很興奮。它可以同時在開發(fā)環(huán)境和生產(chǎn)環(huán)境中運行,只需要將一切打包進(jìn)一個Docker鏡像中,然后通過Docker Hub分發(fā)鏡像,這是很直接了當(dāng)?shù)摹D銜l(fā)現(xiàn)以下過程很令人滿意:你可以快速地將現(xiàn)有的應(yīng)用(如Python應(yīng)用)移植到Docker中,將該容器與另一個數(shù)據(jù)庫容器(如PostgreSQL)連接。但是,你不會想手動啟動一個Docker容器,也不會想自己去實現(xiàn)一個系統(tǒng)來監(jiān)控運行中的容器和重啟未運行的容器。

此時,你會意識到兩個相互關(guān)聯(lián)的挑戰(zhàn):網(wǎng)絡(luò)和服務(wù)發(fā)現(xiàn)。不幸的是,說得好聽一點,這兩個領(lǐng)域都是新興的課題;說得難聽一點,在這兩個領(lǐng)域里,還有很多不確定的內(nèi)容,也缺乏最佳實踐。幸運的是,在海量的博客和文章中,分散著各種各樣的“秘方”。

?

?

本書

因此,我對自己說:如果有人寫本書,可以介紹這些主題,并提供一些基本的指導(dǎo),對于每項技術(shù)給讀者指引正確的方向,那該多好啊。

那個“人”注定是我, 在本書里,我將介紹Docker容器網(wǎng)絡(luò)和服務(wù)發(fā)現(xiàn)領(lǐng)域中的挑戰(zhàn)和現(xiàn)有的解決方案。 我想讓大家了解以下三點:

?

?

  • 服務(wù)發(fā)現(xiàn)和容器編排就像一枚硬幣的兩面。
  • 對于Docker網(wǎng)絡(luò),如果沒有正確的理解和完善的策略,那就糟糕了。
  • 網(wǎng)絡(luò)和服務(wù)發(fā)現(xiàn)領(lǐng)域還很年輕。你會發(fā)現(xiàn),剛開始你還在學(xué)習(xí)一套技術(shù),過一段時間,就會“換擋”,嘗試另一套技術(shù)。不要緊張,這是很正常的。在我看來,在形成標(biāo)準(zhǔn)和市場穩(wěn)定之前,還會有兩三年時間。


編排和調(diào)度

嚴(yán)格來講,編排是比調(diào)度更廣泛的一個概念:編排包含了調(diào)度,同時也包含其他內(nèi)容。例如,容器的故障重啟(可能是由于容器本身不健康,也可能是宿主機(jī)出了故障)。而調(diào)度僅僅是指,決定哪個容器運行在哪個宿主機(jī)上的過程。在本書中,我會無差別地使用這兩個術(shù)語。

我這么做的原因是:第一,在IETF RFC和NIST標(biāo)準(zhǔn)中并沒有對這兩個概念的官方定義;第二,在不同公司的市場宣傳中,往往會故意混淆它們,因此我希望你能對此有所準(zhǔn)備。然而,Joe Beda(前Google和Kubernetes的策劃者)對于該問題發(fā)表了一篇相當(dāng)不錯的文章:?What Makes a Container Cluster?,你可以更深入地了解一下。

?

?

我希望,本書的讀者是:

?

?

  • 開發(fā)者們,正在使用Docker;
  • 網(wǎng)絡(luò)Ops,正在為熱情的開發(fā)者所帶來的沖擊做準(zhǔn)備;
  • (企業(yè))軟件架構(gòu)師,正在將現(xiàn)有負(fù)載遷移到Docker,或者使用Docker開始一項新項目;
  • 最后但同樣重要的是,我相信,分布式應(yīng)用的開發(fā)者、SRE和后端工程師們也能從其中獲取一些價值。


需要注意的是,本書不是一本動手實踐(hands-on)的書籍(除了第二章的Docker網(wǎng)絡(luò)部分),更像是一本指導(dǎo)。當(dāng)你計劃實施一個基于Docker的部署時,你可以參考本書來做出一個明智合理的決定。閱讀本書的另一種方式是,添加大量注釋和書簽(a heavily annotated bookmark collection)。

?

?

我在一個很酷的創(chuàng)業(yè)公司Mesosphere, Inc.(Apache Mesos背后的商業(yè)公司)工作,主要的工作內(nèi)容是幫助DevOps充分利用Mesos。雖然我有偏見地認(rèn)為Mesos是目前進(jìn)行大規(guī)模集群調(diào)度的最佳選擇,但是我仍然會盡我最大的努力來確保這種偏愛不會影響對于各項技術(shù)的介紹。

?

?

致謝

向Mesosphere同事們James DeFelice和Stefan Schimanski(來自Kubernetes組)致謝,他們很耐心地回答了我關(guān)于Kubernetes網(wǎng)絡(luò)的問題。向我的Mesosphere同事們Sebastien Pahl和Tim Fall(原Docker同事)致謝,我非常感謝你們關(guān)于Docker網(wǎng)絡(luò)的建議。也很感謝另一個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)驗和教訓(xùn)。

很感謝Adrian Mouat(容器解決方案)和Diogo Mónica(Docker, Inc.)通過Twitter回答問題,尤其是在普通人睡覺的時候,花了數(shù)小時回答了我的問題。

我也很感謝來自Chris Swan的反饋,他提供了明確可操作的評論。通過解決他的問題,我相信本書變得更有針對性了。

在本書的寫作過程中,來自Google的Mandy Waite提供了很多有用的反饋,特別是Kubernetes,我很感謝這一點。我也很感激Tim Hockin(Google)的支持,他幫助我澄清了很多關(guān)于Docker網(wǎng)絡(luò)特性和Kubernetes的疑惑。

感謝Matthias Bauer對于本書的草稿提出的寶貴意見。

非常感謝我的O’Reilly編輯Brian Anderson。從我們討論草稿開始,你一直都非常支持我,很高效,也很有趣。非常榮幸和您一起工作。

最后重要的一點是,對于我的家庭要致以最深刻的謝意:我的“陽光”Saphira,我的“運動女孩”Ranya,我的兒子和“Minecraft大師”Iannis,以及一直支持我的妻子Anneliese。如果沒有你們的支持,我是不可能完成本書的。

?

?

動機(jī)

2012年2月,Randy Bias發(fā)表了一篇談話,名為開放和可擴(kuò)展云架構(gòu),提出了pets和cattle兩種文化基因的碰撞。

?

?

  • 基礎(chǔ)設(shè)施的pets方法(pets approach to infrastructure),每臺機(jī)器或虛擬機(jī)被當(dāng)做一個個體,會分配一個名字,各個應(yīng)用被靜態(tài)地部署在各個機(jī)器上。例如:?db-prod-2是生產(chǎn)環(huán)境中的一臺數(shù)據(jù)庫服務(wù)器。應(yīng)用是手動部署的,當(dāng)一臺機(jī)器出故障時,你需要修復(fù)它,并把應(yīng)用手動部署到另一臺機(jī)器上。在非云原生應(yīng)用時代(non-cloud-native era),這種方法通常占據(jù)著主導(dǎo)地位。
  • 基礎(chǔ)設(shè)施的cattle方法(cattle approach to infrastructure),所有的機(jī)器都是無名的、完全類似的(modulo hardware upgrades),它們只有編號,沒有名字。應(yīng)用是自動部署到機(jī)器群中的任意一臺。當(dāng)其中一臺機(jī)器發(fā)生故障時,你不需要立刻處理它,只要在方便的時候更換故障機(jī)器(或者它的一部分,如一塊損壞的HDD)。


盡管這些文化基因(meme)最初是針對虛擬機(jī)的,但是我們這里會將cattle方法套用在容器的基礎(chǔ)架構(gòu)上。

?

?

Go Cattle!

在基礎(chǔ)設(shè)施中,使用cattle方法的一大好處就是,你可以在商用硬件上進(jìn)行水平擴(kuò)展。

這樣一來,你就可以有很大的彈性來實施混合云。只要你愿意,一部分可以部署在premise環(huán)境中,一部分部署在公有云上,也可以部署在不同的云提供商的IaaS架構(gòu)上。

更重要的是,從一名運維者的角度上來看,cattle方法可以保證一個相當(dāng)好的睡眠質(zhì)量。因為你再也不會像pets方法中那樣,凌晨3點被叫起來去更換一塊壞了的HDD或者將應(yīng)用重新部署到另一臺服務(wù)器上。

然而,cattle方法也帶來了一些挑戰(zhàn),主要包括以下兩個方面:

?

?

社交挑戰(zhàn)(Social challenges)

我敢說,大部分挑戰(zhàn)會來自于社交方面:我應(yīng)該怎么說服我的老板呢?我怎么讓CTO買我的賬呢?我的同事們會反對這種新的做法嗎?這是不是意味著我們只需要更少的人來維護(hù)基礎(chǔ)架構(gòu)?現(xiàn)在,對于這個問題,我還不能提供一個完整有效的解決方案。你可以買一本《鳳凰項目》,從中你可能可以找到答案。

?

技術(shù)挑戰(zhàn)(Technical challenges)

這個方面主要包括:機(jī)器的準(zhǔn)備機(jī)制(provisioning mechanism)如何選擇(例如,使用Ansible來部署Mesos Agents);在容器之間、在容器和外界之間如何通信;如何保證容器的自動部署并能被尋址(consequently findable)。

?

Docker網(wǎng)絡(luò)和服務(wù)發(fā)現(xiàn)棧

我們在圖1-1中描述了整個技術(shù)棧,包括以下內(nèi)容:

?

?

底層的網(wǎng)絡(luò)層(The low-level networking layer)

這一層包括一系列網(wǎng)絡(luò)工具:?iptables、路由、IPVLAN和Linux命名空間。你通常不需要知道其中的細(xì)節(jié),除非你是在網(wǎng)絡(luò)組,但是你需要意識到這一點。關(guān)于這一課題的更多信息,可以參考Docker網(wǎng)絡(luò)基礎(chǔ)

?

Docker網(wǎng)絡(luò)層

這一層封裝了底層的網(wǎng)絡(luò)層,提供各種抽象模型,例如單主機(jī)橋網(wǎng)絡(luò)模式、多主機(jī)的每個容器一個IP地址的解決方案。在第2章和第3章中有相關(guān)介紹。

?

服務(wù)發(fā)現(xiàn)層/容器編排層

這里,我們將容器調(diào)度定義為通過底層提供的基本原語(primitives)決定將容器放在哪里。第4章提到了服務(wù)發(fā)現(xiàn)的必要背景,第5章從容器編排的角度講解了網(wǎng)絡(luò)和服務(wù)發(fā)現(xiàn)。

軟件定義網(wǎng)絡(luò)(SDN)

SDN真的是一個市場術(shù)語(umbrella term或者marketing term),它可以提供VM帶來的網(wǎng)絡(luò)優(yōu)勢,就像裸機(jī)服務(wù)器(bare-metal servers)一樣。網(wǎng)絡(luò)管理團(tuán)隊會變得更加敏捷,對商業(yè)需求的變化反應(yīng)更加迅速。另一種看法是:SDN是一種使用軟件來定義網(wǎng)絡(luò)的配置方式,可能是通過API構(gòu)建、通過NFV構(gòu)建,或者由Docker網(wǎng)絡(luò)來提供SDN。

如果你是一名開發(fā)者或架構(gòu)師,我建議你看一下Cisco對于該課題的觀點和SDxCentral的文章What’s Software-Defined Networking (SDN)?

?


圖 1-1

如果你在網(wǎng)絡(luò)運維組的話,你可能已經(jīng)準(zhǔn)備好進(jìn)入下一章了。然而,如果你是架構(gòu)師或者開發(fā)者的話,對于網(wǎng)絡(luò)知識可能有點生疏了,我建議你讀一下Linux Network Administrators Guide來復(fù)習(xí)一下相關(guān)知識。

?

我需要All-In嗎?

在各種會議和用戶組中,我經(jīng)常遇到一些人,他們對于容器領(lǐng)域的機(jī)會非常興奮,同時他們也擔(dān)心在從容器中受益之前需要投入多少。以下的表格是對于我了解的各種部署的非正式的總結(jié)(按照階段不同排序)。

?

?


需要注意的是,不是所有的例子都使用Docker容器(顯而易見的是,Google并不使用Docker容器)。其中,某些正在著手使用Docker,例如,在ad-hoc階段;某些正在轉(zhuǎn)向full-down階段,例如Uber,請看ContainerSched 2015 London中的演講。最后重要的一點是,這些階段與部署的大小是沒有必然關(guān)系的。例如,Gutefrage.de只有六臺裸機(jī)服務(wù)器,仍然使用Apache Mesos來管理它們。?

在繼續(xù)之前,還有最后一點:到目前為止,你可能已經(jīng)注意到了我們處理的是分布式系統(tǒng)。由于我們總是希望將容器部署到一個集群中,我強(qiáng)烈建議你讀一下分布式計算的謬論,以防你不熟悉這一主題。

現(xiàn)在言歸正傳,讓我們進(jìn)入Docker網(wǎng)絡(luò)這一主題。

?

Docker網(wǎng)絡(luò)基礎(chǔ)

在我們進(jìn)入網(wǎng)絡(luò)細(xì)節(jié)之前,我們先來看一看在單主機(jī)上發(fā)生了什么。Docker容器需要運行在一臺宿主機(jī)上,可以是一臺物理機(jī)(on-premise數(shù)據(jù)中心中的裸機(jī)服務(wù)器),也可以是on-prem或云上的一臺虛擬機(jī)。就像圖2-1中描述的那樣,宿主機(jī)上運行了Docker的daemon進(jìn)程和客戶端,一方面可以與Docker registry交互,另一方面可以啟動、關(guān)閉和審查容器。

?

?


圖 2-1
宿主機(jī)和容器的關(guān)系是1:N,這以為這一臺宿主機(jī)上可以運行多個容器。例如,從Facebook的報告來看,取決于機(jī)器的能力,每臺宿主機(jī)上平均可以運行10到40個容器。另一個數(shù)據(jù)是:在Mesosphere,我們發(fā)現(xiàn),在裸機(jī)服務(wù)器上的各種負(fù)載測試中,每臺宿主機(jī)上不超過250個容器是可能的。

無論你是在單主機(jī)上進(jìn)行部署,還是在集群上部署,你總得和網(wǎng)絡(luò)打交道:

?

  • 對于大多數(shù)單主機(jī)部署來說,問題歸結(jié)于是使用共享卷進(jìn)行數(shù)據(jù)交換,還是使用網(wǎng)絡(luò)(基于HTTP或者其他的)進(jìn)行數(shù)據(jù)交換。盡管Docker數(shù)據(jù)卷很容易使用,它也引入了緊耦合,這意味著很難將單主機(jī)部署轉(zhuǎn)化為多主機(jī)部署。自然地,共享卷的優(yōu)勢是速度。
  • 在多主機(jī)部署中,你需要考慮兩個方面:單主機(jī)上的容器之間如何通信和多主機(jī)之間的通信路徑是怎樣的。性能考量和安全方面都有可能影響你的設(shè)計決定。多主機(jī)部署通常是很有必要的,原因是單主機(jī)的能力有限(請看前面關(guān)于宿主機(jī)上容器的平均數(shù)量和最大數(shù)量的討論),也可能是因為需要部署分布式系統(tǒng),例如Apache Spark、HDFS和Cassandra。


分布式系統(tǒng)和數(shù)據(jù)本地化(Distributed Systems and Data Locality)

使用分布式系統(tǒng)(計算或存儲)的基本想法是想從并行處理中獲利,通常伴隨著數(shù)據(jù)本地化。數(shù)據(jù)本地化,我指的是將代碼轉(zhuǎn)移到數(shù)據(jù)所在地的原則,而不是傳統(tǒng)的、其他的方式。考慮下以下的場景:如果你的數(shù)據(jù)集是TB級的,而代碼是MB級的,那么在集群中移動代碼比傳輸TB級數(shù)據(jù)更高效。除了可以并行處理數(shù)據(jù)之外,分布式系統(tǒng)還可以提供容錯性,因為系統(tǒng)中的一部分可以相對獨立地工作。

本章主要討論單主機(jī)中的網(wǎng)絡(luò),在第3章中,我們將介紹多主機(jī)場景。

簡單地說,Docker網(wǎng)絡(luò)是原生的容器SDN解決方案。總而言之,Docker網(wǎng)絡(luò)有四種模式:橋模式,主機(jī)模式,容器模式和無網(wǎng)絡(luò)模式。我們會詳細(xì)地討論單主機(jī)上的各種網(wǎng)絡(luò)模式,在本章的最后,我們還會討論一些常規(guī)主題,比如安全。

?

?

bridge模式網(wǎng)絡(luò)

在該模式(見圖2-2)中,Docker守護(hù)進(jìn)程創(chuàng)建了一個虛擬以太網(wǎng)橋docker0,附加在其上的任何網(wǎng)卡之間都能自動轉(zhuǎn)發(fā)數(shù)據(jù)包。默認(rèn)情況下,守護(hù)進(jìn)程會創(chuàng)建一對對等接口,將其中一個接口設(shè)置為容器的eth0接口,另一個接口放置在宿主機(jī)的命名空間中,從而將宿主機(jī)上的所有容器都連接到這個內(nèi)部網(wǎng)絡(luò)上。同時,守護(hù)進(jìn)程還會從網(wǎng)橋的私有地址空間中分配一個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

?

?

注意:
因為bridge模式是Docker的默認(rèn)設(shè)置,所以你也可以使用docker run -d -P nginx:1.9.1。如果你沒有使用-P(發(fā)布該容器暴露的所有端口)或者-p host_port:container_port(發(fā)布某個特定端口),IP數(shù)據(jù)包就不能從宿主機(jī)之外路由到容器中。

?

?


圖 2-2

?

?

小技巧:
在生產(chǎn)環(huán)境中,我建議使用Docker的host模式(將會在下一小節(jié)Host模式網(wǎng)路中討論),并輔以第3章中的某個SDN解決方案。進(jìn)一步地,為了控制容器間的網(wǎng)絡(luò)通信,你可以使用flags參數(shù):--iptables和-icc。

?

?

Host模式網(wǎng)絡(luò)

該模式將禁用Docker容器的網(wǎng)絡(luò)隔離。因為容器共享了宿主機(jī)的網(wǎng)絡(luò)命名空間,直接暴露在公共網(wǎng)絡(luò)中。因此,你需要通過端口映射(port mapping)來進(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ò)時,容器實際上繼承了宿主機(jī)的IP地址。該模式比bridge模式更快(因為沒有路由開銷),但是它將容器直接暴露在公共網(wǎng)絡(luò)中,是有安全隱患的。

?


圖 2-3

?

Container模式網(wǎng)絡(luò)

該模式會重用另一個容器的網(wǎng)絡(luò)命名空間。通常來說,當(dāng)你想要自定義網(wǎng)絡(luò)棧時,該模式是很有用的。實際上,該模式也是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)顯示:第二個容器使用了--net=container參數(shù),因此和第一個容器admiring_engelbart具有相同的IP地址172.17.0.3

?

None模式網(wǎng)絡(luò)

該模式將容器放置在它自己的網(wǎng)絡(luò)棧中,但是并不進(jìn)行任何配置。實際上,該模式關(guān)閉了容器的網(wǎng)絡(luò)功能,在以下兩種情況下是有用的:容器并不需要網(wǎng)絡(luò)(例如只需要寫磁盤卷的批處理任務(wù));你希望自定義網(wǎng)絡(luò),在第3章中有很多選項使用了該模式。

例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ò)沒有任何配置。

你可以在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)建和銷毀容器時,手動分配IP地址是不能接受的。bridge模式可以在一定程度上解決這個問題。為了防止本地網(wǎng)絡(luò)上的ARP沖突,Docker Daemon會根據(jù)分配的IP地址生成一個隨機(jī)地MAC地址。在下一章中,我們會再次討論分配地址的挑戰(zhàn)。

?

分配端口

你會發(fā)現(xiàn)有兩大陣營:固定端口分配(fixed-port-allocation)和動態(tài)端口分配(dynamically-port-allocation)。每個服務(wù)或者應(yīng)用可以有各自的分配方法,也可以是作為全局的策略,但是你必須做出自己的判斷和決定。請記住,bridge模式中,Docker會自動分配UDP或TCP端口,并使其可路由。

?

網(wǎng)絡(luò)安全

Docker可以開啟容器間通信(意味著默認(rèn)配置--icc=true),也就是說,宿主機(jī)上的所有容器可以不受任何限制地相互通信,這可能導(dǎo)致拒絕服務(wù)攻擊。進(jìn)一步地,Docker可以通過--ip_forward--iptables兩個選項控制容器間、容器和外部世界的通信。你應(yīng)該了解這些選項的默認(rèn)值,并讓網(wǎng)絡(luò)組根據(jù)公司策略設(shè)置Docker進(jìn)程。可以讀一下StackEngine的Boyd Hemphill寫的文章Docker security analysis

另一個網(wǎng)絡(luò)安全方面是線上加密(on-the-wire encryption),通常是指RFC 5246中定義的TLS/SSL。注意,在寫本書時,這一方面還很少被討論,實際上,只有兩個系統(tǒng)(下一章會詳細(xì)討論)提供了這個特性:Weave使用NACl,OpenVPN是基于TLS的。根據(jù)我從Docker的安全負(fù)責(zé)人Diogo Mónica那里了解的情況,v1.9之后可能加入線上加密功能。

最后,可以讀一下Adrian Mouat的Using Docker,其中詳細(xì)地介紹了網(wǎng)絡(luò)安全方面。

?

?

小技巧: 自動Docker安全檢查 為了對部署在生產(chǎn)環(huán)境中的Docker容器進(jìn)行安全檢查,我強(qiáng)烈建議使用The Docker Bench for Security。

現(xiàn)在,我們對單主機(jī)場景有了一個基本的了解,讓我們繼續(xù)看一下更有效的案例:多主機(jī)網(wǎng)絡(luò)環(huán)境。

?

?

?

Docker多主機(jī)網(wǎng)絡(luò)

只要是在單主機(jī)上使用Docker的話,那么上一章中介紹的技術(shù)就足夠了。然而,如果一臺宿主機(jī)的能力不足以應(yīng)付工作負(fù)載,要么買一個更高配置的宿主機(jī)(垂直擴(kuò)展),要么你添加更多同類型的機(jī)器(水平擴(kuò)展)。

對于后者,你會搭建一個集群。那么,就出現(xiàn)了一系列問題:不同宿主機(jī)上的容器之間如何相互通信?如何控制容器間、容器和外部世界之間的通信?怎么保存狀態(tài),如IP地址分配、集群內(nèi)保持一致性等?如何與現(xiàn)有的網(wǎng)絡(luò)基礎(chǔ)架構(gòu)結(jié)合?安全策略呢?

為了解決這些問題,在本章中,我們會討論多主機(jī)網(wǎng)絡(luò)的各種技術(shù)。

?

?

?

注意:
對于本章中介紹的各種選項,請記住Docker信奉的是“batteries included but replaceable”,也就是說,總會有一個默認(rèn)功能(如網(wǎng)絡(luò)、服務(wù)發(fā)現(xiàn)),但是你可以使用其他方案來替代。

?

?

Overlay

2015年3月,Docker, Inc.收購了軟件定義網(wǎng)絡(luò)(SDN)的創(chuàng)業(yè)公司SocketPlane,并更名為Docker Overlay驅(qū)動,作為多主機(jī)網(wǎng)絡(luò)的默認(rèn)配置(在Docker 1.9以后)。Overlay驅(qū)動通過點對點(peer-to-peer)通信擴(kuò)展了通常的bridge模式,并使用一個可插拔的key-value數(shù)據(jù)庫后端(如Consul、etcd和ZooKeeper)來分發(fā)集群狀態(tài)。

?

Flannel

CoreOS?Flannel是一個虛擬網(wǎng)絡(luò),分配給每個宿主機(jī)一個子網(wǎng)。集群中的每個容器(或者說是Kubernetes中的pod)都有一個唯一的、可路由的IP地址,并且支持以下一系列后端:VXLAN、AWS VPC和默認(rèn)的2層UDP overlay網(wǎng)絡(luò)。flannel的優(yōu)勢是它降低了端口映射的復(fù)雜性。例如,Red Hat的Atomic項目使用的就是flannel

?

?

Weave

Weaveworks?Weave創(chuàng)建了一個虛擬網(wǎng)絡(luò),用來連接部署在多主機(jī)上的Docker容器。應(yīng)用使用網(wǎng)絡(luò)的方式就像是容器直接插入到同一個網(wǎng)絡(luò)交換機(jī)上,不需要配置端口映射和連接。Weave網(wǎng)絡(luò)上的應(yīng)用容器提供的服務(wù)可以直接在公共網(wǎng)絡(luò)上訪問,無論這些容器在哪里運行。同樣的,無論位置在哪,現(xiàn)有的內(nèi)部系統(tǒng)都是暴露給應(yīng)用容器的。Weave可以穿越防火墻,在部分連接的網(wǎng)絡(luò)中運行。流量可以加密,允許主機(jī)跨越非授信網(wǎng)絡(luò)進(jìn)行連接。你可以從Alvaro Saurin的文章Automating Weave Deployment on Docker Hosts with Weave Discovery中學(xué)習(xí)到Weave的更多特性。

?

?

Project Calico

Metaswitch的Calico項目使用標(biāo)準(zhǔn)IP路由,嚴(yán)格的說是RFC 1105中定義的邊界網(wǎng)關(guān)協(xié)議(Border Gateway Protocol,簡稱BGP),并能使用網(wǎng)絡(luò)工具提供3層解決方案。相反,大多數(shù)其他的網(wǎng)絡(luò)解決方案(包括Weave)是通過封裝2層流量到更高層來構(gòu)建一個overlay網(wǎng)絡(luò)。主操作模式不需要任何封裝,是為可以控制物理網(wǎng)絡(luò)結(jié)構(gòu)的組織的數(shù)據(jù)中心設(shè)計的。

?

?

Open vSwitch

Open vSwitch是一個多層虛擬交換機(jī),通過可編程擴(kuò)展來實現(xiàn)網(wǎng)絡(luò)自動化,支持標(biāo)準(zhǔn)管理接口和協(xié)議,如NetFlow、IPFIX、LACP和802.1ag。除此之外,它還支持在多個物理服務(wù)器上分發(fā),和VMware的vNetwork distributed vSwitch、Cisco的Nexus 1000V類似。

?

?

Pipework

Pipework由著名的Docker工程師Jér?me Petazzoni創(chuàng)建,稱為Linux容器的軟件定義網(wǎng)絡(luò)。它允許你使用cgroups和namespace在任意復(fù)雜的場景中連接容器,并與LXC容器或者Docker兼容。由于Docker, Inc.收購了SocketPlane并引入了Overlay Driver,我們必須看一下這些技術(shù)如何融合。

?

?

OpenVPN

OpenVPN,另一個有商業(yè)版本的開源項目,運行你創(chuàng)建使用TLS的虛擬私有網(wǎng)絡(luò)(virtual private networks,簡稱VPN)。這些VPN也可以安全地跨越公共網(wǎng)絡(luò)連接容器。如果你想嘗試一下基于Docker的配置,我建議看一下DigitalOcean很贊的教程How To Run OpenVPN in a Docker Container on Ubuntu 14.04

?

?

未來的Docker網(wǎng)絡(luò)

在最近發(fā)布的Docker v1.9中,引入了一個新的命令docker network。容器可以動態(tài)地連接到其他網(wǎng)絡(luò)上,每個網(wǎng)絡(luò)都可以由不同的網(wǎng)絡(luò)驅(qū)動來支持。默認(rèn)的多主機(jī)網(wǎng)絡(luò)驅(qū)動是Overlay

為了了解更多實踐經(jīng)驗,我建議看一下以下博客:

?

?

  • Aleksandr Tarasov的Splendors and Miseries of Docker Network
  • Calico項目的Docker libnetwork Is Almost Here, and Calico Is Ready!
  • Weave Works的Life and Docker Networking – One Year On

?

?

更多話題

在本章中,我們討論了多主機(jī)網(wǎng)絡(luò)中的各種解決方案。這一小節(jié)會簡要介紹一下其他需要了解的話題:

?

?

IPVLAN

Linux內(nèi)核v3.19引入了每個容器一個IP地址的特性,它分配給主機(jī)上的每個容器一個唯一的、可路由的IP地址。實際上,IPVLAN使用一個網(wǎng)卡接口,創(chuàng)建了多個虛擬的網(wǎng)卡接口,并分配了不同的MAC地址。這個相對較新的特性是由Google的Mahesh Bandewar貢獻(xiàn)的,與macvlan驅(qū)動類似,但是更加靈活,因為它可以同時使用在L2和L3上。如果你的Linux發(fā)行版已經(jīng)使用了高于3.19的內(nèi)核,那么你很幸運;否則,你就無法享受這個新功能。

?

IP地址管理(IPAM)

多主機(jī)網(wǎng)絡(luò)中,最大的挑戰(zhàn)之一就是集群中容器的IP地址分配

?

編排工具兼容性

本章中討論的大多數(shù)多主機(jī)網(wǎng)絡(luò)解決方案都是封裝了Docker API,并配置網(wǎng)絡(luò)。也就是說,在你選擇其中一個之前,你需要檢查與容器編排工具的可兼容性。更多主題,請看第5章。

?

IPv4 vs. IPv6

到目前為止,大多數(shù)Docker部署使用的是標(biāo)準(zhǔn)IPv4,但是IPv6正在迎頭趕上。Docker從v1.5(2015年2月發(fā)布)開始支持IPv6。IPv4的持續(xù)減少將會導(dǎo)致越來越多的IPv6部署,也可以擺脫NATs。然而,什么時候轉(zhuǎn)變完成還不清楚。

現(xiàn)在,你已經(jīng)對底層網(wǎng)絡(luò)和Docker網(wǎng)絡(luò)的解決方案有了充分理解,讓我們進(jìn)入下一個內(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方法的話,那么你會把所有機(jī)器看做相同的,你不會手動分配某臺機(jī)器給某個應(yīng)用。相反,你會使用調(diào)度軟件來管理容器的生命周期。

那么,問題就來了:如何決定容器被調(diào)度到哪臺宿主機(jī)上?答對了,這就是服務(wù)發(fā)現(xiàn)。我們會在第5章詳細(xì)討論硬幣的另一面:容器編排。

?

?

挑戰(zhàn)

服務(wù)發(fā)現(xiàn)已經(jīng)出現(xiàn)了一段時間了,被認(rèn)為是zeroconf的一部分。

zeroconf

zeroconf的想法是自動化創(chuàng)建和管理計算機(jī)網(wǎng)絡(luò),自動分配網(wǎng)絡(luò)地址,自動分發(fā)和解析主機(jī)名,自動管理網(wǎng)絡(luò)服務(wù)。

對于Docker容器來說,這個挑戰(zhàn)歸結(jié)于穩(wěn)定地維護(hù)運行中容器和位置(location)的映射關(guān)系。位置這里指的是IP地址(啟動容器的宿主機(jī)地址)和可被訪問的端口。這個映射必須及時完成,并在集群中準(zhǔn)確地重啟容器。容器的服務(wù)發(fā)現(xiàn)解決方案必須支持以下兩個操作:

?

?

注冊(Register)

建立container->location的映射。因為只有容器調(diào)度器才知道容器運行在哪,我們可以把該映射當(dāng)做容器位置的“絕對真理”(the absolute source of truth)。

?

查詢(Lookup)

其他服務(wù)或應(yīng)用可以查詢我們存儲的映射關(guān)系,屬性包括信息的實時性和查詢延遲。

讓我們看一下在選擇過程中相對獨立的幾點考慮:

?

  • 除了簡單地向一個特定方向發(fā)送請求之外,怎么從搜索路徑中排除不健康的宿主機(jī)和掛掉的容器?你已經(jīng)猜到了,這是和負(fù)載均衡高度相關(guān)的主題,因為這是很重要的,所以本章的最后一小節(jié)將討論這一主題。
  • 有人認(rèn)為這是實現(xiàn)細(xì)節(jié),也有人認(rèn)為需要考慮CAP三要素。在選擇服務(wù)發(fā)現(xiàn)工具時,需要考慮選擇強(qiáng)一致性(strong consistency)還是高可用性(high availability)。至少你要意識到這一點。
  • 可擴(kuò)展性也會影響你的選擇。當(dāng)然,如果你只有少量的節(jié)點需要管理,那么上面討論的解決方案就夠用了。然而,如果你的集群有100多個節(jié)點,甚至1000個節(jié)點,那么在選擇某一項特定技術(shù)之前,你必須做一些負(fù)載測試。

?

?

CAP理論

1998年,Eric Brewer提出了分布式系統(tǒng)的CAP理論。CAP代表了一致性(consistency)、可用性(availability)和分區(qū)容錯性(partition tolerance):?


一致性
分布式系統(tǒng)的所有節(jié)點同時看到相同的數(shù)據(jù)。?
可用性
保證每個請求都能得到響應(yīng),無論該響應(yīng)是成功還是失敗。
分區(qū)容錯性?
無論哪塊分區(qū)由于網(wǎng)絡(luò)故障而失效,分布式系統(tǒng)都可以繼續(xù)運行。
CAP理論在分布式系統(tǒng)的實踐中已經(jīng)討論多次了。你會聽到人們主要討論強(qiáng)一致性 vs 最終一致性,我建議讀一下Martin Kleppmann的論文A Critique of the CAP Theorem。該論文提出了一種不同的、更實際的思考CAP的方法,特別是一致性。

如果你想了解該領(lǐng)域更多的需求和根本的挑戰(zhàn),可以讀一下Jeff Lindsay的Understanding Modern Service Discovery with Docker和Shopify的Simon Eskildsen在DockerCon分享的內(nèi)容

?

?

技術(shù)

該小節(jié)介紹了各種技術(shù)和它們的優(yōu)缺點,并提供了網(wǎng)上的更多資源(如果你想獲得這些技術(shù)的實踐經(jīng)驗,你可以看看Adrian Mouat的書Using Docker)。

?

?

ZooKeeper

Apache?ZooKeeper是ASF的頂級項目,基于JVM的集中式配置管理工具,提供了與Google的Chubby相兼容的功能。ZooKeeper(ZK)將數(shù)據(jù)載荷組織成文件系統(tǒng),成為znodes的層級結(jié)構(gòu)。在集群中,選舉出一個leader節(jié)點,客戶端能夠連接到服務(wù)器中的任意一個來獲取數(shù)據(jù)。一個ZK集群中需要2n+1個節(jié)點。最常見的配置是3、5、7個節(jié)點。

ZooKeeper是經(jīng)戰(zhàn)場證明的、成熟的、可擴(kuò)展的解決方案,但是也有一下缺點。有些人認(rèn)為ZK集群的安裝和管理不是一個令人愉快的體驗。我碰到的大多數(shù)ZK問題都是因為某個服務(wù)(我想到了Apache Storm)錯誤地使用了它。它們可能在znodes里放入了太多數(shù)據(jù),更糟糕的是,他們的讀寫率很不健康(unhealthy read-write ratio),特別是寫得太快。如果你打算使用ZK的話,至少考慮使用高層接口。例如,Apache Curator封裝了ZK,提供了大量的方法;Netflix的Exhibitor可以管理和監(jiān)控一個ZK集群。

從圖4-1可以看出,你可以看到兩個組件:R/W(作為注冊監(jiān)控器(registration watcher),你需要自己提供)和NGINX(被R/W控制)。當(dāng)一個容器被調(diào)度到一個節(jié)點上時,它會在ZK中注冊,使用一個路徑為/$nodeID/$containerID的znode,IP地址作為數(shù)據(jù)載荷。R/W監(jiān)控znodes節(jié)點的變化,然后相應(yīng)地配置NGINX。這種方法對于HAProxy和其他負(fù)載均衡器也同樣有效。

?


圖 4-1

?

etcd

etcd是由CoreOS團(tuán)隊使用Go語言編寫的。它是一個輕量級的、分布式鍵值對數(shù)據(jù)庫,使用Raft算法實現(xiàn)一致性(帶有l(wèi)eader選舉的leader-follower模型),在集群中使用復(fù)制日志(replicated log)向followers分發(fā)lead收到的寫請求。從某種意義上說,在概念上,etcd和ZK是相當(dāng)類似的。雖然負(fù)載數(shù)據(jù)是任意的,但是etcd的HTTP API是基于JSON的。就像ZK一樣,你可以觀察到etcd保存的值的變化。etcd的一個非常有用的特性是鍵的TTL,是服務(wù)發(fā)現(xiàn)的重要的一個結(jié)構(gòu)單元。和ZK一樣,一個etcd集群至少需要2n+1個節(jié)點。

etcd的安全模型支持基于TLS/SSL和客戶端證書加密的線上加密(on-the-wire encryption),加密可以發(fā)生在客戶端和集群之間,也可以在etcd節(jié)點之間。

在圖4-2中,你可以看到etcd服務(wù)發(fā)現(xiàn)的搭建和ZK是相當(dāng)類似的。主要區(qū)別在于etcd使用confd來配置NGINX,而不是使用自己編寫的腳本。和ZK一樣,這種搭建方法也適用于HAProxy或者其他負(fù)載均衡器。

?


圖 4-2

?

Consul

Consul是HashiCorp的產(chǎn)品,也是用Go語言寫的,功能有服務(wù)注冊、服務(wù)發(fā)現(xiàn)和健康檢查,可以使用HTTP API或者DNS來查詢服務(wù)。Consul支持多數(shù)據(jù)中心的部署。

Consul的其中一個特性是一個分布式鍵值對數(shù)據(jù)庫,與etcd相似。它也是用Raft一致性算法(同樣需要2n+1個節(jié)點),但是部署方式是不同的。Consul有agent的概念,有兩種運行方式:服務(wù)器模式(提供鍵值對數(shù)據(jù)庫和DNS)和客戶端模式(注冊服務(wù)和健康檢查),使用serf實現(xiàn)了成員和節(jié)點發(fā)現(xiàn)。

使用Consul,你有四種方式來實現(xiàn)服務(wù)發(fā)現(xiàn)(從最可取到最不可取):

?

  • 使用服務(wù)定義配置文件(service definition config file),由Consul agent解釋。
  • 使用traefik等工具,其中有Consul后端(backend)。
  • 編寫你自己的進(jìn)程通過HTTP API注冊服務(wù)。
  • 讓服務(wù)自己使用HTTP API來注冊服務(wù)。


想要學(xué)習(xí)Consul來做服務(wù)發(fā)現(xiàn)嗎?請閱讀這兩篇文章:Consul Service Discovery with DockerDocker DNS & Service Discovery with Consul and Registrator。?

?

?

純基于DNS的解決方案

在互聯(lián)網(wǎng)中,DNS經(jīng)受了數(shù)十年的戰(zhàn)場驗證,是很健壯的。DNS系統(tǒng)的最終一致性、特定的客戶端強(qiáng)制性地(aggressively)緩存DNS查詢結(jié)果、對于SRV記錄的依賴這些因素使你明白這是正確的選擇。

本小節(jié)之所以叫做“純基于DNS的解決方案”的原因是,技術(shù)上講Consul也是用了DNS服務(wù)器,但這只是Consul做服務(wù)發(fā)現(xiàn)的其中一個選項。以下是著名的、常用的、純粹的基于DNS的服務(wù)發(fā)現(xiàn)解決方案:

?

?

Mesos-DNS

該解決方案是專門用于Apache Mesos的服務(wù)發(fā)現(xiàn)的。使用Go編寫,Mesos-DNS下拉任意任務(wù)的有效的Mesos Master進(jìn)程,并通過DNS或HTTP API暴露IP:PORT信息。對于其他主機(jī)名或服務(wù)的DNS請求,Mesos-DNS可以使用一個外部的域名服務(wù)器或者你的現(xiàn)有DNS服務(wù)器來轉(zhuǎn)發(fā)Mesos任務(wù)的請求到Mesos-DNS。

?

SkyDNS

使用etcd,你可以將你的服務(wù)通告給SkyDNS,SkyDNS在etcd中保存了服務(wù)定義,并更新DNS記錄。你的客戶端應(yīng)用發(fā)送DNS請求來發(fā)現(xiàn)服務(wù)。因此,在功能層面,SkyDNS與Consul是相當(dāng)類似的,只是沒有健康檢查。

?

WeaveDNS

WeaveDNS由Weave 0.9引入,作為Weave網(wǎng)絡(luò)的服務(wù)發(fā)現(xiàn)解決方案,允許容器按照主機(jī)名找到其他容器的IP地址。在Weave 1.1中,引入了所謂的Gossip DNS,通過緩存和超時功能使得查詢更加快速。在最新的實現(xiàn)中,注冊是廣播到所有參與的實例上,在內(nèi)存中保存所有條目,并在本地處理查詢。

?

Airbnb的SmartStack和Netflix的Eureka

在本小節(jié)中,我們將會看一下兩個定做的系統(tǒng),它們是用來解決特定的需求。這并不意味著你不能或者不應(yīng)該使用它們,你只是需要意識到它們。

Airbnb的SmartStack是一個自動的服務(wù)發(fā)現(xiàn)和注冊框架,透明地處理創(chuàng)建、刪除、故障和維護(hù)工作。在容器運行的同一個宿主機(jī)上,SmartStack使用了兩個分離的服務(wù):Nerve(寫到ZK)用于服務(wù)注冊,Synapse(動態(tài)配置HAProxy)用于查詢。這是一個針對非容器環(huán)境的完善的解決方案,隨著實踐推移,你會看到對于Docker,SmartStack也是有用的。

Netflix的Eureka則不同,它運行在AWS環(huán)境中(Netflix全部運行在AWS上)。Eureka是一個基于REST的服務(wù),用于定位服務(wù)以便負(fù)載均衡和中間件層服務(wù)器的故障遷移;Eureka還有一個基于Java的客戶端組件,可以直接與服務(wù)交互。這個客戶端有一個內(nèi)置的負(fù)載均衡器,可以做基本的round-robin的負(fù)載均衡。在Netflix,Eureka用于做red/black部署、Cassandra和memcached部署、承載應(yīng)用中關(guān)于服務(wù)的元數(shù)據(jù)。

Eureka集群在參與的節(jié)點之間異步地復(fù)制服務(wù)注冊信息;與ZK、etcd、Consul不同,Eureka相對于強(qiáng)一致性更傾向于服務(wù)可用性,讓客戶端自行處理過時的讀請求,優(yōu)點是在網(wǎng)絡(luò)分區(qū)上更有彈性。你也知道的:網(wǎng)絡(luò)是不可靠的

?

負(fù)載均衡

服務(wù)發(fā)現(xiàn)的一個方面是負(fù)載均衡,有的時候負(fù)載均衡被認(rèn)為是正交的,有的時候負(fù)載均衡被認(rèn)為是服務(wù)發(fā)現(xiàn)的一部分。它可以在很多容器之間分散負(fù)載(入站服務(wù)請求)。在容器和微服務(wù)的語境下,負(fù)載均衡同時具有以下功能:

?

?

  • 最大化吞吐量,最小化響應(yīng)時間
  • 防止熱點(hotspotting),例如單一容器過載
  • 可以處理過度激進(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ù)載均衡的信息,請查看Mesos meetup視頻和nginx.conf 2014上關(guān)于NGINX和Consul的負(fù)載均衡的演講

?

?

更多話題

在本章的最后,我列舉了服務(wù)發(fā)現(xiàn)解決方案的一覽表。我并不想評出一個優(yōu)勝者,因為我相信這取決于你的用例和需求。因此,把下表當(dāng)做一個快速定位和小結(jié):

?

?


最后請注意:服務(wù)發(fā)現(xiàn)領(lǐng)域在不斷變化中,每周都會出現(xiàn)新工具。例如,Uber最近開源了它的內(nèi)部解決方案Hyperbahn,一個路由器的overlay網(wǎng)絡(luò),用來支持TChannel RPC協(xié)議。因為容器服務(wù)發(fā)現(xiàn)在不斷發(fā)展,因此你可能要重新評估最初的選擇,直到穩(wěn)定下來為止。

?

容器和編排

就像上一章中介紹的那樣,使用cattle方法來管理基礎(chǔ)架構(gòu),你不必手動為特定應(yīng)用分配特定機(jī)器。相反,你應(yīng)該使用調(diào)度器來管理容器的生命周期。盡管調(diào)度是一個重要的活動,但是它其實只是另一個更廣闊的概念——編排的一部分。

從圖5-1,可以看到編排包括健康檢查(health checks)、組織原語(organizational primitives,如Kubernetes中的labels、Marathon中的groups)、自動擴(kuò)展(autoscaling)、升級/回滾策略、服務(wù)發(fā)現(xiàn)。有時候base provisioning也被認(rèn)為是編排的一部分,但是這已經(jīng)超出了本書的討論范圍,例如安裝Mesos Agent或Kubernetes Kubelet。

服務(wù)發(fā)現(xiàn)和調(diào)度是同一枚硬幣的兩面。決定一個特定的容器運行在集群的哪個節(jié)點的實體,稱之為調(diào)度器。它向其他系統(tǒng)提供了containers->locations的映射關(guān)系,可以以各種方式暴露這些信息,例如像etcd那樣的分布式鍵值對數(shù)據(jù)庫、像Mesos-DNS那樣的DNS。

?

?


圖 5-1

本章將從容器編排解決方案的角度討論服務(wù)發(fā)現(xiàn)和網(wǎng)絡(luò)。背后的動機(jī)很簡單:假設(shè)你使用了某個平臺,如Kubernetes;然后,你主要的關(guān)注點是平臺如何處理服務(wù)發(fā)現(xiàn)和網(wǎng)絡(luò)。

?

?

注意:
接下來,我會討論滿足以下兩個條件的容器編排系統(tǒng):開源的和相當(dāng)大的社區(qū)。
你可以看一下以下幾個不同的解決方案:Fackebook的Bistro或者托管的解決方案,如Amazon EC2的容器服務(wù)ECS。
另外,你如果想多了解一下分布式系統(tǒng)調(diào)度這個主題,我推薦閱讀Google關(guān)于Borg和Omega的研究論文。

在我們深入探討容器編排系統(tǒng)之前,讓我們先看一下編排的核心組件——調(diào)度器到底是做什么的。

?

?

?

調(diào)度器到底是做什么的?

分布式系統(tǒng)調(diào)度器根據(jù)用戶請求將應(yīng)用分發(fā)到一個或多個可用的機(jī)器上。例如,用戶可能請求運行應(yīng)用的100個實例(或者Kubernetes中的replica)。

在Docker中,這意味著:(a)相應(yīng)的Docker鏡像存在宿主機(jī)上;(b)調(diào)度器告訴本地的Docker Daemon基于該鏡像開啟一個容器。

在圖5-2中,你可以看到,對于集群中運行的應(yīng)用,用戶請求了三個實例。調(diào)度器根據(jù)它對于集群狀態(tài)的了解,決定將應(yīng)用部署在哪里。比如,機(jī)器的使用情況、成功啟動應(yīng)用所必須的資源、約束條件(該應(yīng)用只能運行在使用SSD的機(jī)器)等。進(jìn)一步地,服務(wù)質(zhì)量也是考量因素之一。

?

?


圖 5-2

通過John Wilkes的Cluster Management at Google了解更多內(nèi)容。

?

?

警告:
對于調(diào)度容器的限制條件的語義,你要有概念。例如,有一次我做了一個Marathon的demo,沒有按照預(yù)期工作,原因是我沒有考慮布局的限制條件:我使用了唯一的主機(jī)名和一個特定的角色這一對組合。它不能擴(kuò)展,原因是集群中只有一個節(jié)點符合條件。同樣的問題也可能發(fā)生在Kubernetes的label上。

?

?

Vanilla Docker and Docker Swarm

創(chuàng)造性地,Docker提供了一種基本的服務(wù)發(fā)現(xiàn)機(jī)制:Docker連接(links)。默認(rèn)情況下,所有容器都可以相互通信,如果它們知道對方的IP地址。連接允許用戶任何容器發(fā)現(xiàn)彼此的IP地址,并暴露端口給同一宿主機(jī)上的其他容器。Docker提供了一個方便的命令行選項--link,可以自動實現(xiàn)這一點。

但是,容器之間的硬連接(hard-wiring of links)并不有趣,也不具擴(kuò)展性。事實上,這種方法并不算好。長久來說,這個特性會被棄用。

讓我們看一下更好的解決方案(如果你仍然想要或者必須使用連接的話):ambassador模式

?

Ambassadors

如圖5-3所示,這個模式背后的想法是使用一個代理容器來代替真正的容器,并轉(zhuǎn)發(fā)流量。它帶來的好處是:ambassador模式允許你在開發(fā)階段和生產(chǎn)階段使用不同的網(wǎng)絡(luò)架構(gòu)。網(wǎng)絡(luò)運維人員可以在運行時重寫應(yīng)用,而不需要更改應(yīng)用代碼。

簡單來說,ambassador模式的缺點是它不能有效地擴(kuò)展。ambassador模式可以用在小規(guī)模的、手動的部署中,但是當(dāng)你使用真正的容器編排工具(如Kubernetes或Apache Mesos)時,應(yīng)該避免使用ambassador模式。

?

?


圖 5-3

?

?

注意:
如果你想要了解如何在Docker中部署ambassador模式,我再次建議你參考Adrian Mouat的書Using Docker。事實上,在圖5-3中,我使用的就是他的amouat/ambassador鏡像。

?

?

Docker Swarm

除了容器的靜態(tài)鏈接(static linking),Docker有一個原生的集群工具Docker Swarm。Docker Swarm基于Docker API構(gòu)建,并通過以下方式工作:有一個Swarm manager負(fù)載調(diào)度,在每一個宿主機(jī)上運行了一個agent,負(fù)責(zé)本地資源管理(如圖5-4所示)。

Swarm中有趣的地方在于,調(diào)度器是插件式的(plug-able),所以你可以使用除了內(nèi)置以外的其他調(diào)度器,如Apache Mesos。在寫本書的過程中,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)文件來捕捉集群狀態(tài)。最近,一個基于DNS的服務(wù)發(fā)現(xiàn)工具wagl被引入到了Swarm中。

如果你想更多了解Docker Swarm,可以讀一下Rajdeep Dua的幻燈片

?

Kubernetes

Kubernetes(請看圖5-5)是一個opinionated的開源框架,彈性地管理容器化的應(yīng)用。簡單來說,它吸取了Google超過十年的運行容器負(fù)載的經(jīng)驗,我們會簡要地介紹一下。進(jìn)一步地,你總是可以選擇其他開源或閉源的方法來替換Kubernetes的默認(rèn)實現(xiàn),比如DNS或監(jiān)控。

?

?


圖 5-5

以下討論假設(shè)你已經(jīng)熟悉Kubernetes和它的技術(shù)。如果你還不熟悉Kubernetes的話,我建議看一下Kelsey HighTower的Kubernetes Up and Running

Kubernetes中,調(diào)度單元是一個pod,這是a tightly coupled set of containers that is always collocated。pod運行實例的數(shù)目是由Replication Controller定義和指定的。pods和services的邏輯組織是由labels定義的。

在每個Kubernetes節(jié)點上,運行著一個稱為Kubelet的agent,負(fù)責(zé)控制Docker daemon,向Master匯報節(jié)點狀態(tài),設(shè)置節(jié)點資源。Master節(jié)點提供API(例如,圖5-6中的web UI),收集集群現(xiàn)在的狀態(tài),并存儲在etcd中,將pods調(diào)度到節(jié)點上。

?


圖 5-6

?

網(wǎng)絡(luò)

在Kubernetes中,每個pod都有一個可路由的IP,不需要NAT,集群節(jié)點上的pods之間也可以相互通信。pod中的所有容器共享一個端口命名空間(port namespace)和同一個notion localhost,因此沒有必要做端口代理(port brokering)。這是Kubernetes的基本要求,可以通過network overlay來實現(xiàn)。

在pod中,存在一個所謂的infrastructure容器,kubelet實例化的第一個容器,它會獲得pod的IP,并設(shè)置網(wǎng)絡(luò)命名空間。pod中的所有其他容器會加入到infra容器的網(wǎng)絡(luò)和IPC命名空間。infra容器的網(wǎng)絡(luò)啟用了bridge模式(請參考第九頁的bridge模式網(wǎng)絡(luò)),pod中的所有其他容器使用container模式(請參考第11頁的container模式網(wǎng)絡(luò))來共享它的命名空間。infra容器中的初始進(jìn)程實際上什么也沒做,因為它的目的只是提供命名空間的載體。關(guān)于端口轉(zhuǎn)發(fā)的最近的work around可能在infra容器中啟動額外的進(jìn)程。如果infra容器死亡的話,那么Kubelet會殺死pod中所有的進(jìn)程,然后重新啟動進(jìn)程。

進(jìn)一步地,Kubernetes的命名空間會啟動所有control points。其中一個網(wǎng)絡(luò)命名空間的例子是,Calico項目使用命名空間來強(qiáng)化coarse-grained網(wǎng)絡(luò)策略(policy)

?

服務(wù)發(fā)現(xiàn)

在Kubernetes的世界里,有一個服務(wù)發(fā)現(xiàn)的canonical抽象,這是service primitive。盡管pods隨時可能啟動和銷毀因為他們可能失敗(或者pods運行的宿主機(jī)失敗),服務(wù)是長時間運行的:它們提供集群層面的服務(wù)發(fā)現(xiàn)和某種級別的負(fù)載均衡。它們提供了一個穩(wěn)定的IP地址和持久化名字,compensating for the shortlivedness of all equally labelled pods。Kubernetes提供了兩種發(fā)現(xiàn)機(jī)制:通過環(huán)境變量(限制于一個特定節(jié)點上)和DNS(集群層面上的)。

?

Apache Mesos

Apache Mesos?(圖5-7)是一個通用的集群資源管理器,抽象了集群中的各項資源(CPU、RAM等),通過這種方式,集群對于開發(fā)者來說就像一個巨大的計算機(jī)。

在某種程度上,Mesos可以看作是分布式操作系統(tǒng)的內(nèi)核。因此,它從未單獨使用,總是和其他框架一起工作,例如Marathon(用于long-running任務(wù),如web服務(wù)器)、Chronos(用于批量任務(wù))或者大數(shù)據(jù)框架(如Apache Spark或Apache Cassandra)。

?

?


圖 5-7

Mesos同時支持容器化負(fù)載(Docker容器)和普通的可執(zhí)行文件(包括bash腳本、Python腳本、基于JVM的應(yīng)用、一個純粹的老的Linux二進(jìn)制格式),也支持無狀態(tài)和有狀態(tài)的服務(wù)。

接下來,我假設(shè)你已經(jīng)熟悉了Mesos和它的相關(guān)技術(shù)。如果你不熟悉Mesos,我建議你閱讀David Greenberg的書《Building Applications on Mesos》,該書介紹了Mesos,特別是對于分布式應(yīng)用的開發(fā)者。

如圖5-8所示,你可以看到Marathon的UI,使用Apache Mesos來啟動和管理長期運行的服務(wù)和應(yīng)用。

?


圖 5-8

?

網(wǎng)絡(luò)

網(wǎng)絡(luò)特性和能力主要取決于Mesos使用的容器方案:

?

  • 對于Mesos containerizer來說,有一些要求,如Linux內(nèi)核版本要大于3.16,并安裝libnl。開啟網(wǎng)絡(luò)隔離功能之后,你可以構(gòu)建一個Mesos Agent。啟動之后,你可以看到以下輸出:
    ? mesos-slave?--containerizer=mesos?--isolation=network/port_mapping?--resources=ports:[31000-32000];ephemeral_ports:?[33000-35000]
    Mesos Agent會配置成使用非臨時(non-ephemeral)端口31000-32000,臨時(ephemeral)端口33000-35000。所有容器共享宿主機(jī)的IP地址,端口范圍被分配到各個容器上(使用目的端口和容器ID之間的1:1映射)。通過網(wǎng)絡(luò)隔離,你可以定義網(wǎng)絡(luò)性能(如帶寬),使得你能夠監(jiān)控容器的網(wǎng)絡(luò)流量。更多細(xì)節(jié),請看MesosCon 2015 Seattle上的演講Per Container Network Monitoring and Isolation in Mesos。
  • 對于Docker containerizer,請看第二章。

?

?

服務(wù)發(fā)現(xiàn)

盡管Mesos不提供服務(wù)發(fā)現(xiàn)功能,但是有一個Mesos特定的解決方案,在praxis中也很常用:Mesos-DNS(Pure-Play DNS-based Solutions)。然而,還有其他的解決方案,如traefik。如果你對于Mesos中的服務(wù)發(fā)現(xiàn)很感興趣,我們的文檔中有一個專門的章節(jié)介紹它。

?

Hashicorp Nomad

Nomad是HashiCorp開發(fā)的集群調(diào)度器,HashiCorp也開發(fā)了Vagrant。Nomad于2015年9月份引入,主要目的是簡化性。Nomad易于安裝和使用。據(jù)說,它的調(diào)度器設(shè)計受到Google的Omega的影響,比如維護(hù)了集群的全局狀態(tài)、使用優(yōu)化的、高并發(fā)的調(diào)度器。

Nomad的架構(gòu)是基于agent的,它有一個單獨的二進(jìn)制文件,可以承擔(dān)不同的角色,支持滾動升級(rolling upgrade)和draining nodes(為了重新平衡)。Nomad使用了一致性協(xié)議(強(qiáng)一致性)來實現(xiàn)所有的狀態(tài)復(fù)制和調(diào)度,使用gossip協(xié)議來管理服務(wù)器地址,從而實現(xiàn)集群自動化(automatic clustering)和多區(qū)域聯(lián)合(multiregion federation)。從圖5-9可以看到,Nomad agent正在啟動。

?

?


圖 5-9

Jobs定義為HCL格式(HashiCorp-proprietary format)或JSON格式。Nomad提供了命令行接口和HTTP API,來和服務(wù)器進(jìn)程進(jìn)行交互。

接下來,我假設(shè)你已經(jīng)熟悉了Nomad和它的術(shù)語,否則我不建議你讀這一節(jié)。如果你不熟悉的話,我建議你讀一下Nomad: A Distributed, Optimistically Concurrent Schedule: Armon Dadgar, HashiCorp(這是HashiCorp的CTO Armon Dadgar對于Nomad的介紹)和Nomad的文檔

?

網(wǎng)絡(luò)

Nomad中有幾個所謂的任務(wù)驅(qū)動(task drivers),從通用的Java可執(zhí)行程序到qemu和Docker。在之后的討論中,我們將會專注后者。

在寫這篇文章的時候,Nomad要求Docker的版本為1.8.2,并使用端口綁定技術(shù),將容器中運行的服務(wù)暴露在宿主機(jī)網(wǎng)卡接口的端口空間中。Nomad提供了自動的和手動的映射方案,綁定Docker容器的TCP和UDP協(xié)議端口。

關(guān)于網(wǎng)絡(luò)選項的更多細(xì)節(jié),例如端口映射(mapping ports)和標(biāo)簽(labels),我建議你讀一下該文章

?

服務(wù)發(fā)現(xiàn)

v0.2中,Nomad提供了基于Consul的服務(wù)發(fā)現(xiàn)機(jī)制,請參考相關(guān)文檔。其中包含了健康檢查(health checks),并假設(shè)運行在Nomad中的任務(wù)能夠與Consul agent通信(使用bridge模式網(wǎng)絡(luò)),這是一個挑戰(zhàn)。

?

我應(yīng)該用哪個呢?

以下內(nèi)容當(dāng)然只是我的一個建議。這是基于我的經(jīng)驗,自然地,我也偏向于我正在使用的東西。可能有各種原因(包括政治上的原因)導(dǎo)致你選擇一個特定的技術(shù)。

從純粹的可擴(kuò)展性的角度來看,這些選項有以下特點:

?

?


對于少量的節(jié)點來說,自然是無所謂的:根據(jù)你的偏好和經(jīng)驗,選擇以上四個選項中的任意一個都可以。但是請記住,管理大規(guī)模的容器是很困難的

?

  • Docker Swarm可以管理1000個節(jié)點,請參考HackerNews和Docker的這篇博客。
  • Kubernetes 1.0據(jù)說可以擴(kuò)展至100個節(jié)點,并在持續(xù)改進(jìn)中,以達(dá)到和Apache Mesos同樣的可擴(kuò)展性。
  • Apache Mesos可以管理最多50000個節(jié)點。
  • 到目前為止,還沒有資料表明Nomad可以管理多少個節(jié)點。


從工作負(fù)載的角度來看,這些選項有以下特點:

?

?



非容器化(Non-containerized)意味著你可以運行任何Linux Shell中可以運行的程序,例如bash或Python腳本、Java程序等。容器化(containerized)以為你需要生成一個Docker鏡像。考慮到有狀態(tài)服務(wù),當(dāng)今應(yīng)用中的很大一部分需要一些調(diào)整。如果你想更多地學(xué)習(xí)編排工具,請參考:

?

  • Docker Clustering Tools Compared: Kubernetes vs Docker Swarm
  • O'Reilly Radar的Swarm v. Fleet v. Kubernetes v. Mesos


為了完整性,我想介紹這個領(lǐng)域的一個新成員Firmament,這是一個非常不錯的項目。這個項目的開發(fā)者們也是Google的Omega和Borg的貢獻(xiàn)者,這個新的調(diào)度器將任務(wù)和機(jī)器組成了一個流網(wǎng)絡(luò),并運行最小成本優(yōu)化(minimum-cost optimization)。特別有趣的一點是,Firmament不僅可以單獨使用,也可以與Kubernetes和Mesos整合。

?

?

容器的一天

當(dāng)選擇使用哪種容器編排方案時,你需要考慮容器的整個生命流程。

?


圖 5-10

Docker容器典型的生命周期包括以下幾個階段:

?

階段1: dev

容器鏡像(你的服務(wù)和應(yīng)用)從一個開發(fā)環(huán)境中開始它的生命流程,通常是從一名開發(fā)者的筆記本開始的。你可以使用生產(chǎn)環(huán)境中運行的服務(wù)和應(yīng)用的特性請求(feature requests)作為輸入。

?

階段2: CI/CD

然后,容器需要經(jīng)歷持續(xù)集成和持續(xù)發(fā)布(continuous integration and continous delivery),包括單元測試、整合測試和冒煙測試

?

階段3: QA/staging

然后,你可以使用一個QA環(huán)境(企業(yè)內(nèi)部或云中的集群)和/或staging階段。

?

階段4:prod

最后,容器鏡像是部署到生產(chǎn)環(huán)境中的。你也需要有一個策略去分發(fā)這些鏡像。不要忘記以canaries的方式進(jìn)行構(gòu)建,并為核心系統(tǒng)(如Apache Mesos)、潛在的高層組件(如Marathon)和你的服務(wù)和應(yīng)用的滾動式升級(rolling upgrade)做計劃。

在生產(chǎn)環(huán)境中,你會發(fā)現(xiàn)bugs,并收集相關(guān)指標(biāo),可以用來改善下一個迭代(返回到階段1)。

這里討論的大部分系統(tǒng)(Swarm、Kubernetes、Mesos和Nomad)提供了很多指令、協(xié)議和整合點來覆蓋這些階段。然而,在你選擇任何一個系統(tǒng)之前,你仍然需要端到端地試用該系統(tǒng)。

?

社區(qū)是很重要的

當(dāng)選擇編排系統(tǒng)時,另一個你需要考慮的一件方面是背后的社區(qū)。以下是一些指標(biāo):

?

  • 是否由一個正式的實體或流程來管理?例如,Apache軟件基金會或Linux基金會。
  • 郵件列表、IRC頻道、bug/issue追蹤器、Git倉庫(補(bǔ)丁或PR的數(shù)量)是否活躍?看一下歷史情況,但是請?zhí)貏e注意活躍度。一個健康的社區(qū)至少會在其中一個領(lǐng)域非常活躍。
  • 該編排工具是否由一個單一實體實際控制?例如,對于Nomad來說,很明顯的是,HashiCorp具有完全控制權(quán)。那么Kubernetes和Mesos呢?
  • 是否有多個獨立的提供商提供支持?例如,你可以在多個不同的環(huán)境中運行Kubernetes或Mesos,并從很多商業(yè)或非商業(yè)的組織和個人得到幫助。


我們已經(jīng)到了本書的結(jié)尾。在容器的網(wǎng)絡(luò)和服務(wù)發(fā)現(xiàn)方面,你已經(jīng)學(xué)習(xí)到了不少知識。看完本章之后,你已經(jīng)可以選擇和部署容器化應(yīng)用了。如果你希望深入地了解本書中的各個主體,請查看附錄A,附錄A提供了大量的資源列表。

?

?

?

附錄A 參考

以下這些鏈接,有的包含了背景知識,有的包含了一些高級內(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

?

其他高級話題

  • 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(翻譯:夏彬)

《新程序員》:云原生和全面數(shù)字化實踐50位技術(shù)專家共同創(chuàng)作,文字、視頻、音頻交互閱讀

總結(jié)

以上是生活随笔為你收集整理的Docker网络和服务发现的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。