「碼唄學(xué)院」聊一聊互聯(lián)網(wǎng)公司Docker容器化是如何實(shí)踐的拣宏?

簡介

? ? docker容器技術(shù)在17年可謂是熾手可熱鲫骗,docker不僅僅改變了傳統(tǒng)軟件服務(wù)的交付流程,更是為云計算和微服務(wù)大規(guī)模集群管理部署踩晶,提供了強(qiáng)有力的技術(shù)支撐执泰。當(dāng)今各大公司企業(yè)也是把容器化技術(shù)作為不可或缺的技術(shù)戰(zhàn)略,于17年初我們也開始步入docker技術(shù)的生態(tài)圈渡蜻,嘗試進(jìn)行對當(dāng)前服務(wù)做容器化的改造术吝,而持續(xù)交付作為項目開發(fā)流程中較為核心的一步,也是落地實(shí)踐最早一步茸苇。

我們的問題

? ? 17年初排苍,基于微服務(wù)的架構(gòu),僅我們團(tuán)隊內(nèi)的服務(wù)單元已經(jīng)過百学密,特別是經(jīng)歷網(wǎng)站的促銷活動淘衙,機(jī)器擴(kuò)容,資源分配等問題真的是苦不堪言腻暮,除此之外更是有一些困繞已久的問題等待解決:

?? 1.?發(fā)布系統(tǒng)不統(tǒng)一

? ??因?yàn)樯婕暗讲煌Z言的系統(tǒng)開發(fā)彤守,各個系統(tǒng)的構(gòu)建流程都有不同,涉及到node哭靖,C#具垫,Java還有python,發(fā)布到不同服務(wù)器上试幽,需要通過對應(yīng)的發(fā)布系統(tǒng)筝蚕,各個系統(tǒng)之間記錄關(guān)聯(lián)很難核對,不便于追蹤铺坞。

?2.?多環(huán)境的管理

? ? 服務(wù)器資源新增起宽,修改部署的配置比較多,包括打通與發(fā)布系統(tǒng)的環(huán)境相關(guān)聯(lián)济榨,基礎(chǔ)服務(wù)的安裝配燎含,包括node,jdk和tomcat服務(wù)器等腿短。

?3.?環(huán)境的一致性

? ??由于各種歷史問題屏箍,導(dǎo)致項目發(fā)布的測試環(huán)境、集成環(huán)境和產(chǎn)線環(huán)境配置不一致橘忱,給系統(tǒng)問題的排查定位帶來一定的難度赴魁,項目部署目錄,服務(wù)啟動用戶钝诚,甚至包括jdk版本的問題颖御,這些問題同時加重了運(yùn)維工作的復(fù)雜度。

?4.?資源的分配

? ??主要是軟資源的計算分配,因?yàn)榉?wù)單元非常多潘拱,每個服務(wù)單元的內(nèi)存疹鳄,端口分配問題會隨著服務(wù)數(shù)量的增加,越來越難以計算和管理芦岂,CMDB統(tǒng)計不夠?qū)崟r瘪弓,造成最終的結(jié)果就是資源利用率比較低。

微服務(wù)架構(gòu)

? ?選擇docker一個重要的原因禽最,就不得不提到微服務(wù)了腺怯,微服務(wù)相比傳統(tǒng)的服務(wù)采用單體的架構(gòu)方式,部署方式和開發(fā)模式上有很大優(yōu)勢川无。單體架構(gòu)的方式呛占,服務(wù)系統(tǒng)過于龐大臃腫,項目發(fā)布部署風(fēng)險較高懦趋,迭代開發(fā)周期較長晾虑,而微服務(wù)按照業(yè)務(wù)維度進(jìn)行功能模塊拆分,使其各自成為一個可獨(dú)立提供服務(wù)仅叫,可獨(dú)立部署運(yùn)行的單元模塊走贪,通過指定的網(wǎng)絡(luò)協(xié)議模塊之間進(jìn)行通信,并且在開發(fā)模式上惑芭,也是相互獨(dú)立坠狡,大幅提高了項目開發(fā)上線的周期,做到快速迭代遂跟。但是隨著則業(yè)務(wù)復(fù)雜性的提升逃沿,微服務(wù)的集群數(shù)量也會急速上升,帶來的問題就是面對如此多服務(wù)如何高效的管理幻锁,部署凯亮,監(jiān)控等一些問題,而docker處理這些卻有著得天獨(dú)厚的優(yōu)勢哄尔。

我們微服務(wù)架構(gòu)核心采用的框架是基于Spring Boot和Dubbo假消,并且是支持雙協(xié)議的通信,http/https和Dubbo RPC的調(diào)用方式岭接,Dubbo的主要是內(nèi)部模塊調(diào)用依賴富拗,而http的接口主要是提供給異構(gòu)系統(tǒng)的接入。整體的項目架構(gòu)圖如下:


容器化之路

如今再次說到docker的時候鸣戴,我們往往已經(jīng)不僅僅談?wù)摰闹皇莇ocker本身啃沪,因?yàn)閐ocker engine 只是改變了應(yīng)用運(yùn)行時的狀態(tài)管理,更多的我們還關(guān)注到服務(wù)的調(diào)度窄锅,編排创千,網(wǎng)絡(luò)管理,存儲,監(jiān)控追驴,配置管理等等一系列的服務(wù)械哟,docker 儼然已經(jīng)是一個龐大的技術(shù)生態(tài)圈,這個生態(tài)圈里面殿雪,大家比較關(guān)心的其中一個核心服務(wù)的就是容器編排了暇咆,因?yàn)槿萜骶幣艔氐椎母淖兞藗鹘y(tǒng)軟件服務(wù)交付流程,而容器編排則又以k8s 和mesos 為主的居多冠摄,更確切的說糯崎,k8s已經(jīng)不僅僅是作為一個編排工具了几缭,此處暫時不做討論河泳,兩者的選型介紹可后續(xù)關(guān)注,此次也不做過多討論年栓。

我們選擇的容器編排是以mesos為主的拆挥,簡單介紹一個以mesos為核心的各個組件以及服務(wù)依賴。

zk ?注冊中心某抓,這個注冊并不是服務(wù)的注冊纸兔,而是用來管理mesos集群狀態(tài)數(shù)據(jù)的中心服務(wù),通過zk來構(gòu)建一套高可用的mesos集群否副。

mesos-slave ?部署在每個node(主機(jī))節(jié)點(diǎn)的服務(wù)汉矿,用來采集服務(wù)器數(shù)據(jù)信息,執(zhí)行指令备禀。

mesos-master 管理服務(wù)器資源信息洲拇,分派mesos-slave資源調(diào)度指令。

marathon ?資源計算服務(wù)曲尸,根據(jù)應(yīng)用部署需要的資源信息赋续,提供資源分配,并且提供了一套UI另患,通過UI可方便的進(jìn)行管理操作纽乱。

各個組件服務(wù)結(jié)構(gòu)如下圖


鏡像

? ? 我們的服務(wù),主要的包括Java和node兩種類型的服務(wù)昆箕,所以基礎(chǔ)鏡像也根據(jù)不同的版本號鸦列,提供了多種類型。鏡像基礎(chǔ)使用的是alpine的版本鹏倘,鏡像文件非常小敛熬,jdk使用的openjdk,加上啟動服務(wù)的腳本以及其他配置第股,配置內(nèi)容应民,鏡像最終大小100M左右,加上項目打包好以后的鏡像,在150M上下诲锹,當(dāng)然為了一些項目的特殊需求繁仁,也提供了oracle jdk的鏡像版本,但是至今未使用過归园。

構(gòu)建

我們的技術(shù)框架最初是基于Spring Boot黄虱,通過Spring Boot提供的打包插件,可以方便的把項目構(gòu)建成一個運(yùn)行時需要的jar包庸诱,啟動jar包和指定的運(yùn)行時的一些參數(shù)信息捻浦,是通過gitlab統(tǒng)一管理的一些shell文件,通過jenkins構(gòu)建過程桥爽,動態(tài)的把項目的jar包和啟動腳本朱灿,封裝在一起,然后發(fā)布到應(yīng)用服務(wù)器钠四,解壓啟動盗扒。但是如果采用docker部署,這種方式就不可行了缀去,因?yàn)閐ocker部署面向的是鏡像侣灶。

? ? docker鏡像的構(gòu)建方式有多種,最合理的一種莫過于Dockerfile了缕碎,但此時我們產(chǎn)線運(yùn)行的項目已經(jīng)非常多了褥影,一個個往里面添加Dockerfile已經(jīng)不現(xiàn)實(shí),所以就提供了一個Dockerfile模板咏雌,里面標(biāo)注了基礎(chǔ)鏡像信息凡怎,在項目構(gòu)建的流程中,通過獲取一些項目參數(shù)处嫌,動態(tài)生成一個Dockerfile文件栅贴,最后通過docker build生成鏡像文件,然后提交到鏡像庫熏迹,這個過程對于開發(fā)人員完全無感知檐薯,就這樣悄無聲息的完成了項目格式的轉(zhuǎn)化,并且對于不同類型的項目注暗,提供了不同類型的Dockerfile模板坛缕,甚至可以通過項目做定制化。

上面說Dockerfile是動態(tài)生成并且對開發(fā)人員無感知的捆昏,而這個構(gòu)建過程赚楚,也是通過執(zhí)行容器實(shí)現(xiàn)的,通過容器掛載的方式骗卜,把構(gòu)建的結(jié)果顯示在宿主機(jī)上宠页,這整個的過程都做成了docker鏡像左胞,并且使用Dockerfile管理這些鏡像,通過不同的Dockerfile輕而易舉的自定義各個類型項目的構(gòu)建過程举户,比如node項目的構(gòu)建和Java的構(gòu)建不同烤宙,就定義兩個Dockerfile就可以了,統(tǒng)一在gitlab上管理俭嘁,維護(hù)成本變得非常低躺枕。

發(fā)布

? ? 項目構(gòu)建完成,容器的的編排部署供填,主要是通過marathon操作拐云。marathon本身提供了一些對外開放的api接口,這個開放接口也是我們做自動化基石近她。項目構(gòu)建完畢叉瘩,流程并沒有結(jié)束。marathon管理的服務(wù)編排泄私,主要是配置文件房揭,定義應(yīng)用备闲,內(nèi)存晌端,端口,以及健康監(jiān)測都是在配置文件里面管理的恬砂,所以基于此咧纠,我按照格式定義了一個項目,專門來管理這些項目的配置泻骤,并且把這些配置提交到gitlab上進(jìn)行管理漆羔,項目結(jié)構(gòu)如下:

每一個環(huán)境對應(yīng)的目錄下,都是一個marathon的配置文件模板狱掂,之所以是模板演痒,因?yàn)槊看螛?gòu)建生成不同的鏡像tag是系統(tǒng)自動生成的,會動態(tài)替換參數(shù)趋惨,并且調(diào)用marathon的api接口進(jìn)行服務(wù)更新鸟顺,服務(wù)的更新策略也都配置在marathon配置文件中的,整個的構(gòu)建和發(fā)布流程器虾,分為各自獨(dú)立的兩模塊讯嫂,通過一套shell完成,也可以獨(dú)立使用兆沙,但還是為了考慮操作的簡單性欧芽,接入了jenkins,并且通過jenkins增強(qiáng)了權(quán)限控制葛圃,并且對操作記錄可追蹤千扔。構(gòu)建流程結(jié)構(gòu)如下圖:


運(yùn)行

? ? 一開始我們采用docker憎妙,只是拿了部分服務(wù)測試,并非一蹴而就曲楚,全部直接推廣使用尚氛。項目測試運(yùn)行剛上線,開始遇到第一個問題洞渤。寫到這里阅嘶,簡單普及一下docker的網(wǎng)絡(luò)模式,docker的網(wǎng)絡(luò)模式默認(rèn)的四種方式host载迄,bridge讯柔,none和自定義的網(wǎng)絡(luò)模式,host的方式就是容器和主機(jī)共享網(wǎng)絡(luò)空間护昧,容器和主機(jī)共用網(wǎng)絡(luò)端口魂迄,這種方式的弊端不言而喻,就是部署應(yīng)用的時候要關(guān)注服務(wù)器的端口分配惋耙。bridge的方式是采用的獨(dú)立的網(wǎng)絡(luò)空間捣炬,通過虛擬網(wǎng)橋的方式利用主機(jī)的網(wǎng)卡進(jìn)行通信,容器的網(wǎng)絡(luò)空間是獨(dú)立的绽榛,容器內(nèi)部服務(wù)端口和主機(jī)映射端口是隨機(jī)的湿酸。none的形式就是關(guān)閉網(wǎng)絡(luò)模式,這種適合于計算的服務(wù)類型灭美。而自定義的網(wǎng)絡(luò)模式募寨,主要是來解決跨主機(jī)網(wǎng)絡(luò)通信的問題懊缺,每個容器網(wǎng)絡(luò)空間也是各自獨(dú)立的祥国,而我們的服務(wù)主要采用的就是種方式往核,問題也恰恰出在這里。

由于采用的是部分服務(wù)做docker化犁苏,老的服務(wù)可能需要訪問新的服務(wù)硬萍,但是這個時候,老服務(wù)在利用Dubbo調(diào)用新服務(wù)的通信的時候围详,發(fā)現(xiàn)對方注冊是IP地址無法訪問朴乖,原因就是docker容器內(nèi)的Dubbo提供的服務(wù),注冊上去的其實(shí)是個虛擬IP地址短曾,和原有老的服務(wù)根本就不同一個網(wǎng)絡(luò)內(nèi)寒砖。所以網(wǎng)絡(luò)單向是不通的,網(wǎng)絡(luò)調(diào)用結(jié)構(gòu)如下圖:

既然是網(wǎng)絡(luò)的問題嫉拐,那么針對該問題的解決方案也列了幾個:

方案一:所有服務(wù)進(jìn)行docker容器化部署哩都,這樣的話所有服務(wù)就處于同一個虛擬網(wǎng)絡(luò)段內(nèi),但是這個遷移的成本和風(fēng)險非常大婉徘。

方案二:基于物理層面網(wǎng)絡(luò)做修改配置漠嵌,但是這種維護(hù)的成本較大咐汞,可擴(kuò)展性不好。

方案三:更改容器內(nèi)服務(wù)運(yùn)行的網(wǎng)絡(luò)儒鹿,采用host的方式配置化撕,這種方式其實(shí)并沒有充分利用容器化帶來的便利之處,但是確實(shí)最簡單解決這個問題的方法约炎,所以最終考慮植阴,選擇這個方案解決,而后期的優(yōu)化方案圾浅,去Dubbo化掠手。

其實(shí)針對容器網(wǎng)絡(luò)的模塊,這里也只是冰山一角狸捕,未來面臨更復(fù)雜的產(chǎn)線環(huán)境喷鸽,將會遇到更多網(wǎng)絡(luò)的配置問題。

總結(jié)

? ??容器化之路是灸拍,這里僅僅只是起點(diǎn)做祝,本次只是簡單的介紹了最開始容器化項目構(gòu)建交付的流程,實(shí)際上在實(shí)踐中遇到的問題不止如此鸡岗,希望對大家有所幫助混槐,思路上也希望能有共鳴,后續(xù)對相關(guān)細(xì)節(jié)問題還會再次介紹纤房。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末纵隔,一起剝皮案震驚了整個濱河市翻诉,隨后出現(xiàn)的幾起案子炮姨,更是在濱河造成了極大的恐慌,老刑警劉巖碰煌,帶你破解...
    沈念sama閱讀 221,820評論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件舒岸,死亡現(xiàn)場離奇詭異,居然都是意外死亡芦圾,警方通過查閱死者的電腦和手機(jī)蛾派,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,648評論 3 399
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來个少,“玉大人洪乍,你說我怎么就攤上這事∫菇梗” “怎么了壳澳?”我有些...
    開封第一講書人閱讀 168,324評論 0 360
  • 文/不壞的土叔 我叫張陵,是天一觀的道長茫经。 經(jīng)常有香客問我巷波,道長萎津,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 59,714評論 1 297
  • 正文 為了忘掉前任抹镊,我火速辦了婚禮锉屈,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘垮耳。我一直安慰自己颈渊,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 68,724評論 6 397
  • 文/花漫 我一把揭開白布儡炼。 她就那樣靜靜地躺著查蓉,像睡著了一般妹田。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 52,328評論 1 310
  • 那天,我揣著相機(jī)與錄音锹漱,去河邊找鬼。 笑死嗅辣,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的抠忘。 我是一名探鬼主播,決...
    沈念sama閱讀 40,897評論 3 421
  • 文/蒼蘭香墨 我猛地睜開眼祭衩,長吁一口氣:“原來是場噩夢啊……” “哼蝎抽!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起瓢宦,我...
    開封第一講書人閱讀 39,804評論 0 276
  • 序言:老撾萬榮一對情侶失蹤玫镐,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 46,345評論 1 318
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡治笨,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,431評論 3 340
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 40,561評論 1 352
  • 序言:一個原本活蹦亂跳的男人離奇死亡分瘦,死狀恐怖琉苇,靈堂內(nèi)的尸體忽然破棺而出嘲玫,到底是詐尸還是另有隱情,我是刑警寧澤并扇,帶...
    沈念sama閱讀 36,238評論 5 350
  • 正文 年R本政府宣布去团,位于F島的核電站,受9級特大地震影響穷蛹,放射性物質(zhì)發(fā)生泄漏土陪。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,928評論 3 334
  • 文/蒙蒙 一肴熏、第九天 我趴在偏房一處隱蔽的房頂上張望鬼雀。 院中可真熱鬧,春花似錦蛙吏、人聲如沸源哩。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,417評論 0 24
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽励烦。三九已至,卻和暖如春泼诱,著一層夾襖步出監(jiān)牢的瞬間坛掠,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,528評論 1 272
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留屉栓,地道東北人舷蒲。 一個月前我還...
    沈念sama閱讀 48,983評論 3 376
  • 正文 我出身青樓,卻偏偏與公主長得像友多,于是被迫代替她去往敵國和親牲平。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,573評論 2 359

推薦閱讀更多精彩內(nèi)容