通過Mongo, Docker和Rancher創(chuàng)建Node.js應(yīng)用集群

標(biāo)簽: 翻譯 虛擬化 rancher


自從Rancher的Beta版本發(fā)布的幾周以來僧叉,平臺新的調(diào)度和服務(wù)發(fā)現(xiàn)的功能讓我略嗨。為了幫助大家理解這些功能是鬼,今天我將展示如何利用這些功能部署一個且實現(xiàn)了HA的Node.js應(yīng)用集群莹捡。我會用Let's Chat作為示例程序,這是一個八錯的開源的聊天工具边篮,有點像Slack。Rancher的首席架構(gòu)師Darren Shepherd在上次的Rancher Meetup上展示了一點Let's Chat奏甫,如果有興趣可以看一下會議記錄戈轿,但是今天我主要介紹的是部署的一些細(xì)節(jié)。Let's Chat 是一個自托管的聊天應(yīng)用阵子,比較適用于小團(tuán)隊思杯,支持很多功能比如:聊天室,通知,警報色乾,XMPP(可擴(kuò)展通訊和表示協(xié)議)聊天誊册,并且還支持多種認(rèn)證方式∨担可以從Let's Chat的github主頁上得到更多的信息案怯。

原文:
http://rancher.com/clustering-a-node-js-application-with-mongo-docker-and-rancher/

Hussein Galal on August 18, 2015

1 應(yīng)用所需組件

Let's Chat正常運行需要以下幾個組件:

  • Node.js(0.10+)執(zhí)行應(yīng)用代碼
  • MongoDB(2.6+)存儲應(yīng)用數(shù)據(jù)
  • Python(2.7.X)支持應(yīng)用中的一些工具

值得慶幸的是,Let's Chat有自己的Docker image(sdelements/lets-chat)了澎办,鏡像中安裝了應(yīng)用所有的依賴并且定義了應(yīng)用所需的環(huán)境變量嘲碱,比如:LCB_DATABASE_URI,用來定義單個或者多個MongoDB服務(wù)的地址局蚀。

部署一個Mongo后端的Let’s Chat超簡單的麦锯,因為已經(jīng)有可用的Docker compose file了。但我們的目的是建立一個高可用的應(yīng)用集群琅绅,這樣可以解決主機(jī)故障(host failure咋翻譯扶欣?感覺是單點故障),所以奉件,我需要起多個MongoDB容器宵蛀,并創(chuàng)建一個副本集備份多個容器的數(shù)據(jù),當(dāng)主服務(wù)節(jié)點掛掉的時候副本集可以指定一個新的節(jié)點作為主服務(wù)節(jié)點县貌。

Let’s Chat使用mongoose驅(qū)動來連接MongoDB服務(wù)器,通過配置凑懂,可以用它連接一個副本集并把數(shù)據(jù)發(fā)送給新的朱服務(wù)節(jié)點煤痕。

2 Rancher環(huán)境

如果還沒有Rancher環(huán)境,不用擔(dān)心接谨,很輕松就可以搞定的摆碉。總的來說脓豪,我們需要用4個機(jī)器來部署:一個用來運行Rancher巷帝,其他三個用來運行應(yīng)用的容器奋隶。
Rancher可以在任何一個linux(Docker 1.6 or later)上運行汪榔。
執(zhí)行命令:

# docker run -d --restart=always -p 8080:8080 rancher/server

Rancher將會花幾分鐘時間啟動,使用的是主機(jī)的8080端口(命令行中指定的)庶诡。一點Rancher啟動并開始運行笤闯,通過“Add Host”按鈕添加其他三個主機(jī)到Rancher堕阔,可以是通過Docker Machine部署所支持的云上的主機(jī),也可以通過“custom”添加本地主機(jī)颗味。( 翻譯的有點糾結(jié)超陆,待改進(jìn)[Once Rancher is up and running, add three new hosts to your environment by clicking the“Add Host” button, and using either the Docker Machine drivers to deploy hosts on one of the supported clouds, or click on “custom” to add any host to your environment.])

注冊主機(jī)
注冊主機(jī)

只需復(fù)制上圖中Step4的命令復(fù)制粘貼到需要添加的機(jī)器上執(zhí)行即可將主機(jī)注冊到Rancher上。命令中包含了Rancher服務(wù)端的信息以及注冊需要的key浦马,這樣就可以將機(jī)器自動的注冊到Rancher的環(huán)境中了时呀。

另外张漂,也可以通過任何一個自動化工具創(chuàng)建Rancher環(huán)境。我曾經(jīng)創(chuàng)建了一個Ansible roles用來在所有的機(jī)器上安裝Docker并且運行Rancher谨娜,也能實現(xiàn)注冊機(jī)器到Rancher上航攒,有這樣幾個role:

  • Docker Role:安裝并配置Docker在Ubuntu 14.04上
  • Rancher Role:安裝并啟動Rancher 服務(wù)端
  • Rancher Agent:在機(jī)器上運行Rancher agent容器并注冊到Rancher服務(wù)端

可以在playbook中使用這些role來部署Rnacher環(huán)境,最后應(yīng)該有一個3個主機(jī)的環(huán)境(這里應(yīng)該說的是Rancher上注冊了三個主機(jī)[不確定])瞧预。

3 構(gòu)建應(yīng)用集群

環(huán)境準(zhǔn)備好屎债,就可以開始部署應(yīng)用了。在Rancher界面的最上面垢油,點擊”Application”-> 點擊“add stack”盆驹,一個stack就是一組相關(guān)的service的集合,一個service就是執(zhí)行特定功能的容器滩愁,可以在一個或多個主機(jī)上調(diào)度躯喇。

每一個stack定義了服務(wù)發(fā)現(xiàn)的范圍,應(yīng)用可以用來連接不同的service硝枉,比如我們后面就會在一個新的stack中連接Let's Chat與Mongo數(shù)據(jù)庫廉丽。

閱讀Rancher官方文檔可以了解更多service以及其配置信息。我們這次安裝主要包括兩個service:

  • MongoDB數(shù)據(jù)庫 service.
  • 應(yīng)用程序service.

3.1 部署MongoDB數(shù)據(jù)庫 service

我已經(jīng)修改了Let’s Chat的MongoDB鏡像妻味,使每一個容器都能自動的連接到副本集正压,為了實現(xiàn)這個功能,我寫了一個python的小腳本责球,把它加到了entrypoint.sh里面焦履,在原始的鏡像中,entrypoint.sh負(fù)責(zé)啟動MongoDB服務(wù)雏逾,你可以在Github中找到嘉裤。

這個腳本首先檢測運行MongoDB的容器的IP,然后將其連接到MongoDB主服務(wù)栖博,并把自己加到副本集里面屑宠,如果它發(fā)現(xiàn)MongoDB服務(wù)的數(shù)量小于3個,就不會進(jìn)行連接仇让,因為這表示沒有已經(jīng)啟動的副本典奉。(有點費解……[The script will first detect the IP of the running MongoDB container and then tries to connect to the primary MongoDB server and add itself to the existing replica set, if it finds that less than three MongoDB servers exist it will not initiate a connection because it means that no replication has been started.])

這個鏡像需要一個環(huán)境變量:MONGO_SERVICE_NAME,它的默認(rèn)值是“mongo”妹孙,它的目的是用來查找已經(jīng)啟動的MongoDB容器的IP秋柄,這個功能是由Rancher中的DNS服務(wù)提供的,所有的容器的IP都會被加到DNS服務(wù)中的同一個service名下蠢正。

那我們先從MongoDB service開始骇笔,點擊“Add New Service”進(jìn)入service的配置頁面:

配置service
配置service

注意,配置頁面中的command中“-replSet letschat”指定了服務(wù)是作為副本集“l(fā)etschat”的一部分,也可以分配一個主機(jī)上的卷笨触,保證數(shù)據(jù)的安全懦傍。

掛在卷
掛在卷

我們想要在每一個主機(jī)上運行一個MongoDB容器,所以在scale里選擇Always run one instance of this containeron every host芦劣,可以使每一個主機(jī)上都運行一個容器粗俱,實現(xiàn)可擴(kuò)展。

現(xiàn)在啟動這個service就可以看到在每一個主機(jī)上都運行了一個容器:

3.2 部署應(yīng)用程序service

現(xiàn)在創(chuàng)建一個運行應(yīng)用程序的service虚吟,也就是在每一個主機(jī)上都運行一個“Let's Chat”容器寸认。我如果用原始的Docker鏡像連接分布式的Mongo后端,就會產(chǎn)生些問題串慰。

問題
第一個問題是當(dāng)應(yīng)用程序的service連接到mongo service偏塞,比如叫“mongo”,會使let’s chat只連接一個MongoDB服務(wù)器邦鲫,但這個服務(wù)器可能不是主服務(wù)幾點灸叼,這種情況下寫入的數(shù)據(jù)沒有備份。

解決辦法
為了解決這個問題我調(diào)整了let's chat容器來執(zhí)行一個python腳本連接Rancher的DNS服務(wù)庆捺,并查找到所有的MongoDB容器古今,然后修改Let’s Chat的環(huán)境變量LCB_DATABASE_URI來添加MongoDB容器的IP列表,現(xiàn)在mongoose驅(qū)動就會將請求重新路由到主服務(wù)器滔以,比如新的LCB_DATABASE_URI:

mongodb://x.x.x.x:27017,y.y.y.y:27017/letschat

會代替原來的:

mongodb://mongo:27017/letschat

需要給腳本提供兩個環(huán)境變量:MONGO_SERVICE_NAME捉腥,提供要搜索的mongo服務(wù)的名字,用來得到所有相關(guān)的容器IP你画;RANCHER_CLUSTER但狭,如果不想原來的Docker鏡像改變可以不使用。

下面開始配置應(yīng)用程序的service:

配置應(yīng)用程序service
配置應(yīng)用程序service

注意我添加了mongo as a service links撬即,因為一旦一個service鏈接另一個的話,一個DNS記錄就會自動的被映射到每一個容器上呈队,也可以被其他服務(wù)的容器發(fā)現(xiàn)剥槐。
環(huán)境變量的設(shè)置:

環(huán)境變量設(shè)置
環(huán)境變量設(shè)置

想要看到整個service的配置,可以查看自動生成的docker-compose.yml和rancher-compose.yml文件:
docker-compose.yml:

docker-compose.yml
docker-compose.yml

rancher_compose.yml:

rancher_compose.yml
rancher_compose.yml

3.3 啟動應(yīng)用

我們啟動的第一個service是MongoDB宪摧,啟動后我們需要對MongoDB服務(wù)器間的備份做一些配置:

進(jìn)入到一個mongo服務(wù)器粒竖,然后執(zhí)行下面的命令進(jìn)行初始化:

> config = {
    "_id" : "letschat",
    "members" : [
      {"_id" : 0, "host" : "<private-ip-of-the-1st-container>:27017"},
      {"_id" : 1, "host" : "<private-ip-of-the-2nd-container>:27017"},
      {"_id" : 2, "host" : "<private-ip-of-the-3rd-container>:27017"}
   ] }
> rs.initiate(config)
letschat:PRIMARY>

這個步驟不需要每一次我們添加或者移除主機(jī)的時候都做,修改的MongoDB鏡像會處理這個的几于。啟動副本集后蕊苗,我們可以啟動其他的service,可以看到這樣的效果:

應(yīng)用啟動效果
應(yīng)用啟動效果

現(xiàn)在如果可以查看下每一個主機(jī)上letschat容器的日志就可以看到:

mongodb://10.42.249.151:27017,10.42.236.117:27017,10.42.211.234:27017/letschat
lets-chat@0.4.2 prestart /usr/src/app
migroose
> lets-chat@0.4.2 start /usr/src/app
> node app.js
██╗     ███████╗████████╗███████╗     ██████╗██╗  ██╗ █████╗ ████████╗
██║     ██╔════╝╚══██╔══╝██╔════╝    ██╔════╝██║  ██║██╔══██╗╚══██╔══╝
██║     █████╗     ██║   ███████╗    ██║     ███████║███████║   ██║
██║     ██╔══╝     ██║   ╚════██║    ██║     ██╔══██║██╔══██║   ██║
███████╗███████╗   ██║   ███████║    ╚██████╗██║  ██║██║  ██║   ██║
══════╝╚══════╝   ╚═╝   ╚══════╝     ╚═════╝╚═╝  ╚═╝╚═╝  ╚═╝   ╚═╝
Release [33m0.4.2[39m

這表明修改過的letschat鏡像能夠檢測到所有服務(wù)名為mongo的已經(jīng)啟動的MongoDB容器沿彭。

3.4 添加Load Balancer

另一個不錯的功能是load balancer朽砰,下面的例子中我將添加一個load balance,更多的關(guān)于Load Balancers的信息,可以參考文檔瞧柔。

首先在stack中點擊“Add Load Balancer”, 下面的選項使得負(fù)載均衡以輪詢的方式處理請求漆弄,但是會做會話的Stickiness配置(the following options will make the load balancer to distribute requests in round robin fashion but with a session stickiness翻譯的有點難受啊)

添加負(fù)載均衡
添加負(fù)載均衡

示例中的load balancer連接到了我們已經(jīng)創(chuàng)的letschat service上造锅,并且會輪詢service下的所有容器撼唾,,[]下面是stickiness選項,保證同一個會話的請求會路由到相同的服務(wù)器上哥蔚,應(yīng)用使用了一個名叫connect.sid的cookie倒谷。

Stickiness配置
Stickiness配置

創(chuàng)建好load balancer后,就可以通過訪問load balancer的地址來使用應(yīng)用了:

訪問應(yīng)用
訪問應(yīng)用

3.5 測試擴(kuò)展性

為了確保應(yīng)用是可伸縮的糙箍,所以創(chuàng)建一個新機(jī)器渤愁,注冊到rancher上,檢查配置好的容器會自動運行并添加到集群中:

這里寫圖片描述
這里寫圖片描述

這里寫圖片描述
這里寫圖片描述

這表示新的主機(jī)已經(jīng)被成功添加進(jìn)去倍靡,容器也自動的在其上運行了猴伶,也可以檢查新的mangodb容器,會顯示已經(jīng)添加到了副本集中:

2015-07-27T02:09:12.139+0000 I REPL     [WriteReplSetConfig] Starting replication applier threads
2015-07-27T02:09:12.141+0000 I REPL     [ReplicationExecutor] New replica set config in use: { _id: "letschat", version: 6, members: [ { _id: 0, host: "10.42.236.117:27017", arbiterOnly: false, ……...

我希望這會對理解怎么使用Rancher調(diào)度mongo副本集有幫助塌西。Letschat對于學(xué)習(xí)部署容器化的他挎,帶容錯的應(yīng)用,是一個非常好的例子捡需。如果有興趣用手上的Rancher嘗試一下办桨,可以在github上下載,加入Beta可以獲得更多的支持站辉,有任何問題都可以訪問我們的論壇呢撞,或者注冊我們下個月的線上會議提問,和開發(fā)們聊饰剥。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末殊霞,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子汰蓉,更是在濱河造成了極大的恐慌绷蹲,老刑警劉巖,帶你破解...
    沈念sama閱讀 211,743評論 6 492
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件顾孽,死亡現(xiàn)場離奇詭異祝钢,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)若厚,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,296評論 3 385
  • 文/潘曉璐 我一進(jìn)店門拦英,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人测秸,你說我怎么就攤上這事疤估≡殖#” “怎么了?”我有些...
    開封第一講書人閱讀 157,285評論 0 348
  • 文/不壞的土叔 我叫張陵做裙,是天一觀的道長岗憋。 經(jīng)常有香客問我,道長锚贱,這世上最難降的妖魔是什么仔戈? 我笑而不...
    開封第一講書人閱讀 56,485評論 1 283
  • 正文 為了忘掉前任,我火速辦了婚禮拧廊,結(jié)果婚禮上监徘,老公的妹妹穿的比我還像新娘。我一直安慰自己吧碾,他們只是感情好凰盔,可當(dāng)我...
    茶點故事閱讀 65,581評論 6 386
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著倦春,像睡著了一般户敬。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上睁本,一...
    開封第一講書人閱讀 49,821評論 1 290
  • 那天尿庐,我揣著相機(jī)與錄音,去河邊找鬼呢堰。 笑死抄瑟,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的枉疼。 我是一名探鬼主播皮假,決...
    沈念sama閱讀 38,960評論 3 408
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼骂维!你這毒婦竟也來了惹资?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 37,719評論 0 266
  • 序言:老撾萬榮一對情侶失蹤航闺,失蹤者是張志新(化名)和其女友劉穎布轿,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體来颤,經(jīng)...
    沈念sama閱讀 44,186評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,516評論 2 327
  • 正文 我和宋清朗相戀三年稠肘,在試婚紗的時候發(fā)現(xiàn)自己被綠了福铅。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 38,650評論 1 340
  • 序言:一個原本活蹦亂跳的男人離奇死亡项阴,死狀恐怖滑黔,靈堂內(nèi)的尸體忽然破棺而出笆包,到底是詐尸還是另有隱情,我是刑警寧澤略荡,帶...
    沈念sama閱讀 34,329評論 4 330
  • 正文 年R本政府宣布庵佣,位于F島的核電站,受9級特大地震影響汛兜,放射性物質(zhì)發(fā)生泄漏巴粪。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 39,936評論 3 313
  • 文/蒙蒙 一粥谬、第九天 我趴在偏房一處隱蔽的房頂上張望肛根。 院中可真熱鬧,春花似錦漏策、人聲如沸派哲。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,757評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽芭届。三九已至,卻和暖如春感耙,著一層夾襖步出監(jiān)牢的瞬間褂乍,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,991評論 1 266
  • 我被黑心中介騙來泰國打工抑月, 沒想到剛下飛機(jī)就差點兒被人妖公主榨干…… 1. 我叫王不留树叽,地道東北人。 一個月前我還...
    沈念sama閱讀 46,370評論 2 360
  • 正文 我出身青樓谦絮,卻偏偏與公主長得像题诵,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子层皱,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 43,527評論 2 349

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