架構(gòu)師小組交流會:每期選一個時下最熱門的技術(shù)話題進(jìn)行小組交流。
第一期主題:容器實(shí)踐。Docker 作為當(dāng)前最具顛覆性的開源技術(shù)之一,其輕量虛擬化、可移植性是CI/CD,DevOps,微服務(wù)的重要實(shí)現(xiàn)技術(shù)。但目前技術(shù)還不夠成熟,在生產(chǎn)實(shí)踐中會遇到不少坑。本期參與小組交流的是國內(nèi)較早采用 Docker 實(shí)踐的公司。參與嘉賓:滬江架構(gòu)師黃凱、滴滴架構(gòu)師田智偉、蘑菇街架構(gòu)師張振華、蘑菇街運(yùn)維架構(gòu)師向靖、七牛技術(shù)總監(jiān)袁曉沛、扇貝技術(shù)總監(jiān)丁彥
第一輪:自由交流滬江黃凱:大家好,我是來自滬江的 Java 架構(gòu)師,我叫黃凱。在加入滬江之前,曾在 HP 和 IBM 的云計算部門擔(dān)任核心開發(fā)和架構(gòu)職位。對 IaaS、Paas、SaaS,尤其是云存儲有較深入的了解。2015 年加入滬江,擔(dān)任架構(gòu)師職位,主導(dǎo)的產(chǎn)品有:課件云存儲,云轉(zhuǎn)碼等等。在這些項(xiàng)目中,我們使用 Mesos 和 Marathon 做 Docker 的編排工具,并開發(fā)了一個 Mesos Framework 做云轉(zhuǎn)碼的核心框架。
那么我們?yōu)槭裁匆褂?Docker,也是機(jī)緣巧合。由于我們的服務(wù)開始的時候不是特別多,采用的就是一種普通的架構(gòu),后來隨著服務(wù)的增多,發(fā)現(xiàn)部署和運(yùn)維花的時間太長,我們想使用一些新的方式。開始的時候研究過 Openstack,后來覺得 Openstack 慢慢沒落,于是我們就選中現(xiàn)在使用的 Docker。我們并不把 Docker 當(dāng)成 VM 在用,而是使用它的原生的,在 Baremetal 上直接安裝 Docker,這樣運(yùn)行效率比在 VM 運(yùn)行 Docker 要來的快。課件云是由很多微服務(wù)組成,不光是一些存儲,這種微服務(wù)是使用 Docker 部署,就相當(dāng)于編排,把這些微服務(wù)部署上去。轉(zhuǎn)碼這一塊是使用了 Mesos 框架,和 Docker 沒有特別大的關(guān)系,但是轉(zhuǎn)碼的應(yīng)用程序,比如說我們現(xiàn)在應(yīng)用 FFmpeg,這個程序是運(yùn)行在 Docker 里面的。
為什么要選擇 Marathon?第一,我覺得 Mesos+Marathon 非常的容易理解。我們也研究過 Kubernetes 和其他的一些方法,發(fā)現(xiàn)從運(yùn)維和研究的方面來說的話,Kubernetes 實(shí)在是太重而且太復(fù)雜,后來選擇了Marathon。我們現(xiàn)在是內(nèi)部服務(wù)使用,兩個部門在使用轉(zhuǎn)碼集群,大概是 Baremetal 有 20 臺的物理機(jī)。除去我們 API 的一些服務(wù),還有一些第三方組件的服務(wù)的話,大概是有 400 多個 Docker 容器在跑。
滴滴田智偉:大家好,我是滴滴代駕事業(yè)部架構(gòu)師,代駕事業(yè)部是公司最早嘗試 Docker 虛擬化的事業(yè)部。目前主要方向是業(yè)務(wù)系統(tǒng)及部分中間件的 Docker 化,我們做的時間也不太長,半年多的時間。線上是因?yàn)槲覀冇欣系囊惶装l(fā)布系統(tǒng),集成涉及的部門比較多,所以我們基于原來的發(fā)布系統(tǒng)完成了預(yù)發(fā)布環(huán)境 Docker 的部署。線下環(huán)境基于 Docker+K8s 開發(fā)內(nèi)部的自動化持續(xù)交付系統(tǒng)及開發(fā)測試環(huán)境管理。我們在做開發(fā)和測試環(huán)境的自動化,另一方面也是做環(huán)境管理的,兩套環(huán)境。對于項(xiàng)目并行的時候發(fā)現(xiàn)原來很多不夠用,原來很多配置是基于端口綁死的情況。現(xiàn)在基于開發(fā) Kubernetes 的話,網(wǎng)絡(luò)隔離用了一部分,然后主要是用環(huán)境變量這一部分,主要考慮是解決一個配置可以應(yīng)用到在多個環(huán)境的情況,基于這個需求才用它。開發(fā) Kubernetes 基于 Namespace,同一個服務(wù)在不同的 Namespace 下,它其實(shí)環(huán)境變量名可以是相同的,但是IP不同,而這一部分 IP 其實(shí)是由開發(fā) Kubernetes 自己去管理的。基于環(huán)境變量獲取一些配置的話,比如 IP 地址這種,就可以做到拿一份配置可以打出多套環(huán)境。
考慮業(yè)務(wù)的安全性和穩(wěn)定性,線上基于純 Docker 的方式在做。我們是基于裸的 Docker 來工作,主要是用資源隔離,沒有借助調(diào)度框架,也沒有自動伸縮。我們是兩步走,一步是驗(yàn)證 Docker,其次是做開發(fā) Kubernetes 線下使用和預(yù)研。為什么沒有考慮 Mesos?剛才跟滬江的同學(xué),我們的考慮是相反的。Mesos 側(cè)重點(diǎn)更專一一點(diǎn),首先不會有模塊的劃分,比如 Kubernetes 有 Replication controller ,Namespace 這種概念,而 Mesos 下幾乎沒有這種概念。我們拿 Kubernetes 主要是做一些編排的功能,而正好開發(fā) Kubernetes 在整個發(fā)布和編排上,體系更全面一點(diǎn)。Mesos 最早是做資源管理,基于 Docker 做一個 Framework 接進(jìn)來的話,它不是專門為編排而生。Kubernetes 首先解決我們的問題是,我們可能不需要加多份配置就可以搭多套不同的環(huán)境,它就是基于 Namespace 做一個多租戶的概念,會對 Service 做一層隔離,對于動態(tài)配置,擴(kuò)容這一部分暫時我們沒用到,確實(shí)用到的一些場景比較少。主要是做不同環(huán)境的隔離,并沒有太多使用編排細(xì)節(jié)上的東西,動態(tài)伸縮之類的目前線下沒有太大必要,線上可能會用到。
蘑菇街向靖:大家好,我是子騫,來自蘑菇街的運(yùn)維架構(gòu)師。我們接下來會做一個 Paas 平臺,想做 Docker 和結(jié)合虛擬機(jī)以及我們用到公有云產(chǎn)品,做成一個混合云的架構(gòu)平臺。我們現(xiàn)在 Docker 也在用,更多的是當(dāng)虛擬機(jī)用,后面我們想基于 Docker 原生的方式去用,可能會涉及資源調(diào)度,服務(wù)發(fā)現(xiàn)的問題。除了 Docker,我們還會用到公有云,公有云更多是虛擬機(jī)的方式提供。出于混合云,想在資源層做一個抽象,對于上層業(yè)務(wù)來講它沒有關(guān)系,它是跑在 Docker 上,還是云主機(jī)上,還是 KVM 虛擬機(jī)上,那么我想在這上面做一個抽象。另外還有,剛才我也是提問滴滴架構(gòu)師的問題,配置怎樣和代碼做隔離,這個也是我考慮的問題。因?yàn)槲铱?Docker 用了環(huán)境變量,通過環(huán)境變量做一些配置的參數(shù)的傳遞,但是在虛擬機(jī)上,特別是在物理機(jī)上,通過環(huán)境變量的方式,我還在考慮有沒有安全的風(fēng)險,Docker 可能是一個只讀的,不會被修改的,但是對于虛擬機(jī)以及物理機(jī)來說,可能會存在被修改的風(fēng)險。
蘑菇街張振華:大家好,我叫張振華,花名郭嘉,我是 14 年從思科加入蘑菇街。我們算是國內(nèi)用 Docker 比較早的,我們一開始用 Docker 是 1.3.2 的版本,當(dāng)時我們采用集群管理工具還是Openstack,因?yàn)楫?dāng)時 Kubernetes 還不是很成熟。當(dāng)時也走了一些彎路,比如我們把 Docker 當(dāng)成虛擬機(jī)來用,曾經(jīng)在線上的規(guī)模也達(dá)到幾百臺虛擬機(jī)幾千個容器,但是我們逐步發(fā)現(xiàn)不能把 Docker 當(dāng)成虛擬機(jī)來使用,因此我們做了一個轉(zhuǎn)型,從去年開始研究 Kubernetes,現(xiàn)在 Kubernetes 加 Docker 的版本開發(fā)完成了,準(zhǔn)備逐步上線。
我們?yōu)槭裁催x用 Kubernetes?編排工具的選擇我們也是做過一番調(diào)研的,它們沒有誰好誰不好這一說,只能說誰更貼切你的需求。對于我們蘑菇街來說,我們需要解決是資源利用率的問題,和運(yùn)維的對接,我們需要有預(yù)發(fā)和線上環(huán)境的持續(xù)集成持續(xù)部署的過程,還有我們需要有對資源的隔離,對部署的快速迭代,包括集群管理,這些方面,我們覺得 Kubernetes 更加適合于我們。
在網(wǎng)絡(luò)方面,我們研究過現(xiàn)在在開源界比較常用的一些方案,但是我們都覺得不太適合,比較 Fannel,Caico 等等,他們一般用的技術(shù)都是 Vxlan,或者是用 BGP。因?yàn)槲覀冎皩?Openstack 的網(wǎng)絡(luò)是比較有經(jīng)驗(yàn)的,然后我們發(fā)現(xiàn)有一個項(xiàng)目,具體名字不記得,Neutron 和 Kubernetes 做一個對接,我們在這個項(xiàng)目的基礎(chǔ)上做了 Vlan 的方案,我們的網(wǎng)絡(luò)沒有用 Vxlan 來做,而是選擇 Vlan 來做,這樣的話一個 Docker 它可以獲得跟一個物理理同一個網(wǎng)絡(luò)平面的 IP,我們的應(yīng)用程序可以直接對外訪問,因?yàn)槲覀儍?nèi)部業(yè)務(wù)有這個需求選擇這個方案。雖然 Docker 內(nèi)部網(wǎng)絡(luò)和外部網(wǎng)絡(luò)是通的,但 Docker 還是獨(dú)立的一個網(wǎng)段,不需要一層 NAT 的轉(zhuǎn)換。我們直接走二層的,是在交換機(jī)走 Chunk,本來物理機(jī)交換機(jī)的 Access 口,這樣的話,一臺物理機(jī)上面允許跑多個vlan的容器,比如說 A業(yè)務(wù)和 B業(yè)務(wù)要走隔離的話,通過網(wǎng)絡(luò)的 Vlan 走隔離,它們的數(shù)據(jù)之間不會有干擾。
Load Balance 我們還沒有涉及到這一塊,Load Balance 我們應(yīng)該會在 nginx 上做一層。因?yàn)閾?jù)我了解,現(xiàn)在 Kubernetes 這一塊 Proxy 還不是很成熟,這上面還存在一些問題,因此還不敢用 Kubernetes 現(xiàn)有提供的服務(wù)。服務(wù)發(fā)現(xiàn)和注冊這一塊我們還在做開發(fā),這塊會和配置管理中心打通。我們內(nèi)部也有其他團(tuán)隊(duì)在做這些功能,所以我們會和內(nèi)部的中間件團(tuán)隊(duì)合作。
七牛云袁曉沛:大家好,我是七牛云數(shù)據(jù)處理技術(shù)總監(jiān)袁曉沛。我們的數(shù)據(jù)處理業(yè)務(wù)包括了圖片和視頻的實(shí)時在線及異步處理。數(shù)據(jù)處理的業(yè)務(wù)量比較大,日均請求量達(dá)到百億級。平臺采用容器技術(shù)的原因是借助容器技術(shù)快速部署,啟動的特性,數(shù)據(jù)處理程序可以根據(jù)數(shù)據(jù)處理量快速地彈性伸縮。借助容器技術(shù)內(nèi)核級別的資源隔離和訪問控制,每個數(shù)據(jù)處理程序可以運(yùn)行在一個私有的環(huán)境,不被其它程序所干擾,保證其上運(yùn)行數(shù)據(jù)是安全可靠的。而且容器技術(shù)是輕量的,它以最小的資源損耗提供資源隔離和訪問控制,而資源特別是計算資源在數(shù)據(jù)處理中是非常寶貴的。
我們在資源調(diào)度上采用的是 Mesos,而二層的業(yè)務(wù)調(diào)度框架則是自己自研的。七牛自身擁有近千臺的物理機(jī),容器是直接運(yùn)行的物理機(jī)上,可以減少虛擬層對資源的消耗,提高資源的利用率。
在網(wǎng)絡(luò)上,對于七牛的自定義數(shù)據(jù)處理服務(wù)直接使用的是 Host 模式,而對第三方數(shù)據(jù)處理服務(wù)則使用的是 Bridge 模式,因?yàn)檫@些程序是用戶自己部署運(yùn)行的,并不知道用戶是否有開啟其他的端口使用,所以使用的是 Bridge 模式,需要對外使用端口的都需要通過 NAT 進(jìn)行暴露,這樣服務(wù)內(nèi)部使用了什么端口并不會對外界環(huán)境造成影響,對平臺環(huán)境做了非常好的安全隔離。我們是使用 Consul 做注冊中心,支持跨數(shù)據(jù)中心的服務(wù)發(fā)現(xiàn)。我們?yōu)槭裁醋匝械恼{(diào)度框架,而不用 Marathon。因?yàn)?Marathon 不支持跨數(shù)據(jù)中心的內(nèi)部服務(wù)或外部服務(wù)的發(fā)現(xiàn),而七牛有多個數(shù)據(jù)中心,影響整體的調(diào)度,其次如果選用 Marathon 的話,根據(jù)我們業(yè)務(wù)的特點(diǎn),還是要再做一層對 Marathon 的包裝才能作為 Dora 的調(diào)度服務(wù),這樣模塊就會變多,部署運(yùn)維會復(fù)雜。
扇貝丁彥:大家好,我是扇貝的技術(shù)總監(jiān)丁彥,之前在暴走漫畫,先后在暴走漫畫和扇貝設(shè)計和主導(dǎo)了基于 Docker 的微服務(wù)架構(gòu)系統(tǒng),以及數(shù)據(jù)收集和分析系統(tǒng)。去年來到扇貝,這里是 Python 的開發(fā)環(huán)境。后來發(fā)現(xiàn)業(yè)務(wù)增長快,水平擴(kuò)展一些機(jī)器,出現(xiàn)問題需要換個機(jī)器等等,都需要非常熟悉業(yè)務(wù)的少數(shù)開發(fā)去做。另外公司對預(yù)算控制嚴(yán)格,機(jī)器基本都是滿負(fù)荷運(yùn)作,平時也不可能多開空置的機(jī)器,已有的機(jī)器還要根據(jù)負(fù)載情況調(diào)整服務(wù)分布情況,所以這種切換服務(wù),增刪服務(wù)的操作還是比較頻繁的。因此,我們用了2-3個月的時間將所有的運(yùn)行環(huán)境都切換到 Docker上,這大大提高了我們的運(yùn)維能力。
Docker 包裝有幾個好處。第一個好處是,環(huán)境升級非常方便。因?yàn)橹灰猵ull 一下最新的鏡像,啟動一個 Container,環(huán)境就升級了。而如果直接基于公有云的鏡像升級的話就很難,因?yàn)橐慌_機(jī)器上跑哪些服務(wù)其實(shí)不一定是固定的,并且之前做的鏡像只要有一臺機(jī)器是還基于它的話,就刪除不掉的,鏡像數(shù)量又有上限。所以docker 非常好地解決了我們的問題。
其次是環(huán)境的顆粒度會更小,一臺機(jī)器上配好幾個應(yīng)用的話,往往配著配著,到最后你就不太能精確地記得上面裝的程序或者庫是給哪個應(yīng)用服務(wù)的,應(yīng)用之間如果依賴有版本的沖突也很難調(diào)和。你想做些服務(wù)的遷移,把負(fù)載比較小的放一起,把負(fù)載比較大的抽出來,這個時候就非常痛苦,但你如果用 Docker 包裝后就非常簡單,只要在不同的機(jī)器上起不同的 Container,就可以實(shí)現(xiàn)這一點(diǎn)。
第三,我們不光用了 Docker,還加入了服務(wù)發(fā)現(xiàn),剛剛討論配置管理這些,我們一并做了。Docker 啟動時候,我們自己寫了一些工具,可以自定義Docker啟動參數(shù),包括配置參數(shù),比如說,一些程序要運(yùn)行的參數(shù),我們主要用兩種方式,一種方式是通過環(huán)境變量灌進(jìn)去,還有一種方式讓程序的啟動腳本支持參數(shù),然后拼接不同的參數(shù)灌進(jìn)去,最終都是落實(shí)到Docker的啟動命令上。服務(wù)發(fā)現(xiàn)是基于 Consul,Docker 的啟動命令是從 Consul 里取的。首先 Consul有 HTTP 的 API,我們是自己寫的 pip 包,只要 Include 一下這個包就可以了,Docker 的服務(wù)啟動后會自動注冊到 Consul。比如要在負(fù)載后加一個服務(wù),只需要找到一臺機(jī)器,啟動對應(yīng)的container,剩下的事情它自己會到 Consul,注冊它的參數(shù)地址一系列東西,自動把它加進(jìn)去。所以這些都是自動化的,如果檢測那臺機(jī)器/服務(wù)掛了,Health Check 也會到 Consul 里面更新。該增加機(jī)器就增加機(jī)器,該下線就下線。總體來說,我們的生產(chǎn)環(huán)境全部跑在 Docker 上面的,然后區(qū)分有狀態(tài)和無狀態(tài)兩種,有狀態(tài)的定死在機(jī)器上,無狀態(tài)的靈活的自由切換。還有一點(diǎn),如果是有狀態(tài)的容器要定死在機(jī)器上的時候,我們一般來說都會采取冗余的結(jié)構(gòu),至少保證有兩個在運(yùn)行,一個掛了,保證整體的服務(wù)在運(yùn)行。其次基于 Docker,我們還做了一套數(shù)據(jù)搜集以及分析的機(jī)制。數(shù)據(jù)搜集是基于日志來搜集的,利用 Docker 的 Log driver,把日志打到 Filter,把結(jié)果存在存儲服務(wù)上。同時監(jiān)控也是基于日志做的。第三部分非生產(chǎn)環(huán)境,比如開發(fā)環(huán)境跟測試環(huán)境都是 Docker 做的,因?yàn)槲覀兠恳粋€服務(wù)都做了 Image、鏡像,用容器方式跑的。通過參數(shù)來決定啟動方式的,我們可以在開發(fā)環(huán)境以及測試環(huán)境采用不同的參數(shù)來啟動容器。 通過 Consul 來隔離的,因?yàn)?Consul 的服務(wù)發(fā)現(xiàn),開發(fā)、生產(chǎn)、測試環(huán)境在不同的自動發(fā)現(xiàn)框架里不會相互影響到。目前機(jī)器在 120 臺左右,基于云服務(wù)。有些基礎(chǔ)的東西不需要依賴于 Docker,比如說申請?jiān)浦鳈C(jī),申請的時候就可以指定它的 CPU 和內(nèi)存這些服務(wù)器資源的配置。所以這部分東西還是屬于 Human schedule,不是完全讓編排的系統(tǒng)自己決定該怎么樣。
編排工具我們現(xiàn)在在研究進(jìn)一步,我剛來這工作的時候,所有的服務(wù)沒有一個跑在 Docker 上面的,我現(xiàn)在把它遷進(jìn)來。現(xiàn)在數(shù)據(jù)增長,已經(jīng)有一些編排的瓶頸,現(xiàn)在在做調(diào)研,可能基于 Swarm,做自動編排的設(shè)計。
第二輪話題交流主持人:容器多的情況下 Kubernetes 存在性能問題,各位在這方面有沒有好的經(jīng)驗(yàn)?
扇貝丁彥:我們其實(shí)也遇到了這個問題,找不到辦法所以放棄了 Kubernetes。我們也是用公有云,網(wǎng)絡(luò)直接依賴公有云的網(wǎng)絡(luò),有可能是因?yàn)楣性圃斐傻模覜]有試過在祼機(jī)上試過。滬江黃凱:Kuberneters 的 Fannel 有一種模式是 Vxlan,它的封裝折包是做內(nèi)核里做的,效率會高一點(diǎn)。容器多就會效率會低是因?yàn)椋?Kubernetes 1.2 的時候,走這樣的一種模式,數(shù)據(jù)先到內(nèi)核態(tài)中,然后把數(shù)據(jù)拉回到用戶態(tài),用 Proxy的方式分發(fā)給各個容器當(dāng)中的。其實(shí)在Kubernetes 1.3以后,它直接在iptables里設(shè)規(guī)則,相當(dāng)于用戶數(shù)據(jù)不用跑到用戶態(tài),在內(nèi)核直接分發(fā)出去了,這種效率會非常高。所以可以研究一下Kubernetes新版本。扇貝丁彥:我們碰到過網(wǎng)絡(luò)方面的問題。默認(rèn)的Docker engine的啟動參數(shù)里面有個iptables,不知道大家有沒有定制化過,如果不定制化這個參數(shù),它默認(rèn)會幫你建iptables的轉(zhuǎn)發(fā)規(guī)則,并會開啟內(nèi)核的網(wǎng)絡(luò)追蹤的模塊。一開始我們沒有注意這件事情,當(dāng)我們的Nginx遷到Docker的時候,Nginx服務(wù)瞬間會掛。后來查原因,是因?yàn)檫@些參數(shù)會開啟網(wǎng)絡(luò)追蹤模塊。因?yàn)槲覀兊腘ginx流量非常大,當(dāng)時只有3臺Linux云主機(jī),分發(fā)Http請求的,然后會導(dǎo)致3臺Linux宿主機(jī),內(nèi)存會被刷破,網(wǎng)絡(luò)會出現(xiàn)堵塞。所以我們關(guān)掉了 iptables 參數(shù),并采用Host的網(wǎng)絡(luò)模型。所以它的容器拿到的IP就是Host的IP。我們一開始也想上一些Kubernetes這些東西,然后發(fā)現(xiàn)簡單跑個模型根本跑不起來,所以一開始就放棄了這一套東西,直接搞了個裸的Docker。
主持人:關(guān)于跨數(shù)據(jù)中心容器集群的使用,大家有經(jīng)驗(yàn)么?滬江黃凱:我們跨數(shù)據(jù)中心主要是IP分配上的問題,我們現(xiàn)在也在嘗試使用Calico,如果Host網(wǎng)絡(luò)是通的話,那么它的內(nèi)部網(wǎng)絡(luò)也就通了,可以自由劃Vlan,這樣你就可以解決跨Data center的問題。還有一個問題就在跨Data center時,服務(wù)注冊與發(fā)現(xiàn)的問題。這個問題也困擾我們很久了,我們現(xiàn)在使用Consul做服務(wù)注冊與發(fā)現(xiàn)。雖然Consul它是官方支持跨Data center,但是我們在使用當(dāng)中的話會發(fā)現(xiàn)注冊的IP,在另外一個注冊中心,它會發(fā)現(xiàn)的比較慢,甚至有時候出現(xiàn)IP沖突的時候。我們的做法是把 Host 的 IP 地址直接用 Environment 的形式注到 Docker 鏡像內(nèi)部,接下 來 Docker 鏡像要注冊,它就會讀取 app 的 IP,然后發(fā)送給 Consul,只要保證 Host 的 IP 和 Docker內(nèi)部容器的 IP 能夠互通的就行了。如果不能通的話,比如說完全和 Host IP 隔離,那么起碼有幾臺機(jī)器要暴露出去,又比如說,Consul 它本身自己要暴露出去才能訪問到。Host 的 IP 是容器啟動之后注進(jìn)去的,啟動命令中把 Host 的 IP 地址加在 -e 的后面,容器在啟動之后,它的環(huán)境就會有這么一個 IP。我們用 Mesos 就沒這個問題,但是用 Kubernetes 就有這個問題。Mesos 會自動幫你把這些東西注入容器中去。滴滴田智偉:其實(shí) Kubernetes 本身也是可以解決這個問題,我們現(xiàn)在在做線下持續(xù)交付的時候。定義完 Service 之后,容器會同一個 Namespace 默認(rèn)加一個系統(tǒng)環(huán)境變量。滬江黃凱:我們試過,在 Pod 啟動之后,Pod 里容器想訪問 host 的 IP 地址,是沒有辦法做到的。蘑菇街張振華:因?yàn)槲覀冎耙灿龅竭@個問題,然后我們業(yè)務(wù)方,他們可能有一些程序會獲取本機(jī) IP 地址,如果是內(nèi)部的 IP 地址,他們程序可能會出現(xiàn)問題,于是我們當(dāng)時沒有用 Docker 默認(rèn)的網(wǎng)絡(luò),而是采用 Vlan。
主持人:我們提到好多 Mesos、Kubernetes、網(wǎng)絡(luò),發(fā)現(xiàn)沒有提自動伸縮,有沒有項(xiàng)目涉及到容器的自動伸縮?滬江黃凱:我們滬江是基于 Mesos+Marathon 做了自己的一個服務(wù),它這個服務(wù)是干嘛的呢,就是監(jiān)測,不停的監(jiān)測每一個 Docker 的 CPU 和內(nèi)存的利用率,一旦超過百分之多少以后,就向Marathon發(fā)一個命令,說我要擴(kuò)容,它還可以支持時間點(diǎn),比如 15 分鐘監(jiān)測一次,如果在 15 分鐘發(fā)現(xiàn)它超過閾值了,就馬上擴(kuò)容出來,但是縮的話,不是適用于頻繁監(jiān)控,如果小于 20% 的話就會縮,一旦縮的話會影響線上用戶的請求。怎么辦呢?我們在縮的時候可以規(guī)定它的時間點(diǎn),比如半夜里2-3點(diǎn),訪問量少于多少點(diǎn)時候把它縮掉。我們監(jiān)測的是 Docker 內(nèi)部的 CPU 的使用率。就是監(jiān)測一個服務(wù),它可以監(jiān)控所有同一服務(wù)的 Container,比如一個服務(wù)有100個容器,那么這一百多個 CPU 利用率加起來除于一百,相當(dāng)于平均的利用率。如果平均利用率超過 80%了,那說明這個集群到了擴(kuò)展程度了,它會以一種比例來擴(kuò)展。針對單個容器,可以設(shè)置內(nèi)存的限制。我們給每一個容器呢,比如它只能用 4 個 CPU,只能用 8G 的內(nèi)存,或者更小一點(diǎn)的內(nèi)存,這些都設(shè)好,設(shè)好之后它自動擴(kuò)展相同規(guī)格的容器。這么做是因?yàn)?Cgroup 有個問題,當(dāng)利用率到達(dá)了啟動的限制,Cgroup 會把這個容器 kill 掉。這個是不可理喻的問題,所以我們想到用 Load scale 來擴(kuò)容,不讓他直接死掉。滴滴田志偉:關(guān)于自動擴(kuò)容,我們線下的時候遇到一個問題,我們最早的時候是用騰訊的公有云,它限制了 NET 的模塊,導(dǎo)致我們最初用 Cgroup 的方案去做,綁定端口。內(nèi)部使用所有應(yīng)用,端口是要做分配的,要不然出現(xiàn)端口沖突。然后遇到問題是,在這種情況下,如果要做動態(tài)擴(kuò)容的話,它每次先創(chuàng)建一個,再殺掉一個,導(dǎo)致每次起來的時候就起不來了,因?yàn)槎丝诘膯栴}。服務(wù)啟動的時候端口是隨機(jī),會出現(xiàn)沖突問題,因?yàn)橛玫氖?Host 的模式。
主持人:關(guān)于自動伸縮為什么沒有考慮到請求數(shù)?因?yàn)槿绻麅?nèi)存占用率如果超過一定預(yù)支,那么請求數(shù)也可能超過一定預(yù)支了。把單個容器所處理的請求數(shù)給限定了,那么它內(nèi)存自然不會超,然后也不會被干掉。滬江黃凱:我個人認(rèn)為,第一,請求數(shù)很難測,你不知道請求數(shù)到多少時要擴(kuò)容,還不如根據(jù) CPU 到 80%,或者 90% 來的直觀。我們的 API 也是根據(jù) CPU 來算的。你真正是高并發(fā)的 API 的話,我也測過,最后我們能夠監(jiān)測到的,其實(shí)還是 CPU 和內(nèi)存。扇貝丁彥:我們擴(kuò)容是根據(jù)響應(yīng)時間,跟請求數(shù)類似,請求數(shù)定指標(biāo)不太好定,我們是根據(jù)響應(yīng)時間,比如平時的響應(yīng)時間是 50 毫秒,當(dāng)響應(yīng)時間是 300 毫秒的時候就要擴(kuò)容了。
主持人:大家對于容器有狀態(tài)無狀態(tài)有沒有遇到什么問題?大家一般用容器的本地磁盤還是共享磁盤呢?滬江黃凱:關(guān)于存儲,我們是有一些研究的。現(xiàn)在容器存儲問題分為兩種,Kubernetes 官方支持一種理念,任何一種存儲都是一個 Volume。Volume 先于 Docker 存在的,而不是 Docker 啟動之后再掛載 Volume。不管是網(wǎng)絡(luò)存儲還是本地存儲,全部以卷的形式,掛載在 Pod 里面或者是宿主機(jī)上,以 Driver mapper 來驅(qū)動這個 Volume,來讀到你所要的內(nèi)容。還有一種情況,就是 Docker 公司主導(dǎo)的存儲模型,任何的存儲都是一種驅(qū)動。如果你想用 NFS 或者如 Ceph 這樣分布式存儲的話,讓 Ceph 開發(fā) Docker 的驅(qū)動,Docker run 的時候指定存儲的驅(qū)動,Docker storage driver這種方式,外部的存儲在容器內(nèi)部它展現(xiàn)形式可以是目錄,也可以是掛載卷、塊的形式。如果用塊掛載到容器中,這個容器自己格式化它,或直接讀取它都是可以的。它只不過它是相當(dāng)于用了一個 Driver 的形式,把你的容器和分布式存儲建立一個連接而已。對于容器,如果原本綁定塊或 Volume,容器出現(xiàn)故障的話,直接把容器殺掉,再啟動掛在同樣一個 塊或Volume就解決了。優(yōu)點(diǎn)是直接讀取,而不是通過再轉(zhuǎn)一層,效率比較高一點(diǎn)。所有存儲都是Volume 的形式理解度比較高一點(diǎn),所以我們還是贊同于用 Volume 的形式。有狀態(tài)的容器。我知道k8s的新的計劃,如果你沒有用 Kubernetes 最新版本的話,一般來說我們都是容器啟動在固定Host 上,下次啟動還是在這臺 Host 上,它的存儲它的內(nèi)存,包括一些 log,全部是在這臺 Host 上。還有一種是用最新的版本,有個 PetSet的新kind,Kubernetes 它自己會記錄 Pod 在什么 Host 上啟動過,不用自己去指定一定要在某一臺 Host 上啟動,這種方法比較智能化,但是不是特別穩(wěn)定的一種方法,因?yàn)樗莿倓傞_發(fā)出來的新功能。
主持人:數(shù)據(jù)多副本,假設(shè)有一個節(jié)點(diǎn)故障的話,是建議它直接把原來的副本重新綁定還是重新起一個新的實(shí)例,通過分布式數(shù)據(jù)的遷移呢?滬江黃凱:我個人認(rèn)為還是在同一臺機(jī)器上起一個新的實(shí)例,不要讓它做數(shù)據(jù)遷移,因?yàn)閿?shù)據(jù)遷移會占用很多資源。而且如果你的想法是說,所有的分布式的存儲只是以 Volume 的形式掛載在宿主同上,這也就沒什么問題了。因?yàn)榇鎯?Docker 是完全分開來的。如果只有一個 Volume,存儲的可靠性會得不到保障,所以在 Kubernetes 新版本當(dāng)中,它會建立一個Volume的kind,也相當(dāng)于建立 RC kind一樣,是一個 Pod,那這樣由 Kubernetes 來保障這個 Volume 的高可用。
轉(zhuǎn)貼: 網(wǎng)易新聞