Ansible部署Node.js

課程指數(shù)

難度指數(shù): 4星(滿星5星)
技術(shù)指數(shù): 5星(滿星5星)
理論指數(shù): 3星(滿星5星)
面向人群: 自動(dòng)化運(yùn)維&初中級(jí)運(yùn)維

分享目錄

1.1 添加額外的源 1
1.2 部署一個(gè)Node.js app 4
1.3 運(yùn)行一個(gè)Node.js app 6
1.4 Node.js app服務(wù)器總結(jié)。 7
1.5 問題: 7

下面我們將要在我們的CentOS6.x服務(wù)器上配置Nodejs硬萍,啟動(dòng)一個(gè)簡單的nodejs實(shí)例绊起,這個(gè)服務(wù)器有很簡單的架構(gòu)际跪。

開始了洲劣,首先創(chuàng)建一個(gè)playbook文件,我們盡量讓它保持簡單。

---
- hosts: all
  tasks:

定義一些運(yùn)行這個(gè)playbook的主機(jī)默责,然后下面列出一系列的tasks。

1.1 添加額外的源

在準(zhǔn)備應(yīng)用一個(gè)服務(wù)器的時(shí)候咸包,為了確保指定些軟件包可以用或者在最新的版本桃序,管理員經(jīng)常首先添加額外的源。
下面的腳本烂瘫,我們想要添加EPEL和Remi源媒熊,以便于我們可以得到類似node.js的軟件包。如果使用shell腳本處理的話坟比,如下所示芦鳍。

 # 導(dǎo)入 Remi GPG 密鑰 – 請參閱: http://rpms.famillecollet.com/RPM-GPG-KEY-remi
wget http://rpms.famillecollet.com/RPM-GPG-KEY-remi \
 -O /etc/pki/rpm-gpg/RPM-GPG-KEY-remi
rpm --import /etc/pki/rpm-gpg/RPM-GPG-KEY-remi
 
# 安裝 Remi repo, Remi repo里面包含了很多的PHP擴(kuò)展
rpm -Uvh --quiet \
http://rpms.famillecollet.com/enterprise/remi-release-6.rpm
 
# 安裝EPEL源
yum install epel-release
 
 # 安裝 Node.js (npm + 和它的依賴關(guān)系).
 yum --enablerepo=epel install npm

這個(gè)shell腳本用于導(dǎo)入EPEL和Remi的GPG keys葛账,然后添加這源柠衅,最后安裝Nodejs。這對(duì)于簡單的部署是沒有問題的籍琳,但是運(yùn)行這么多命令是比較笨的方法菲宴,如果你的連接不小心斷開了贷祈,那么你的腳本也會(huì)停止的。而如果這個(gè)時(shí)候喝峦,你的腳本剛準(zhǔn)備完成呢势誊?

提示:如果你想跳過指定的步驟,你可以跳過添加GPG keys的步驟谣蠢,只需要在運(yùn)行命令的時(shí)候加上—nogpgcheck.或者在Ansible中键科,yum模塊中設(shè)置disable_gpg_check參數(shù)為yes,但是最好還是添加GPG keys漩怎。使用GPG勋颖,你可以知道包的作者是誰,包有沒有修改稿勋锤,除非你知道你正在做什么饭玲,否則最好不要禁止GPG檢查。

Ansible讓事情變的更有健壯性叁执,下面使用Ansible的案例顯得更加詳細(xì)茄厘,它和上面的shell腳本有同樣的功能,但是更容易理解谈宛,更加結(jié)構(gòu)化次哈。 下面使用了Ansible的變量和其它的一些有用的特性。接著上面的playbook吆录,我們繼續(xù)往下寫窑滞。

  tasks:
   - name: Import Remi GPG key
     rpm_key: "key={{ item }} state=present"
     with_items:
       - "http://rpms.famillecollet.com/RPM-GPG-KEY-remi"
   - name: Install Remi repo.
     command: "rpm -Uvh --force {{ item.href }} creates={{ item.creates }}"
     with_items:
       - href: "http://rpms.famillecollet.com/enterprise/remi-release-6.rpm"
         creates: "/etc/yum.repos.d/remi.repo"

   - name: Install epel repo
    yum: name=epel-release state=present

   - name: Stop the firewall
     service: name=iptables state=stopped
 
   - name: Install NodeJS and npm
     yum: name=npm state=present enablerepo=epel

我們看一下具體步驟。

  1. rpm_key 是一個(gè)的Ansible模塊用于從你的RPM數(shù)據(jù)庫中添加或移除GPG key恢筝。我們正在從Remi的源中導(dǎo)入一個(gè)key哀卫。
  2. 因?yàn)锳nsible沒有rpm命令,因此我們使用command模塊來使用rpm命令撬槽,這樣我們可以做其它的兩件事情此改。
    a) 使用creatse參數(shù)告訴Ansible什么時(shí)候不運(yùn)行這個(gè)命令,這個(gè)例子里侄柔,我們告訴Ansible共啃,這個(gè)命令成功執(zhí)行后,將會(huì)創(chuàng)建那些文件暂题。當(dāng)這個(gè)文件存在的時(shí)候移剪,這個(gè)命令將不會(huì)運(yùn)行。
    b) 使用with_items定義一個(gè)URL和用于creates檢查的文件敢靡。
  3. yum負(fù)責(zé)安裝EPEL源挂滓。
  4. 因?yàn)檫@個(gè)服務(wù)器我們將用來做測試用,所以我們使用service模塊禁止系統(tǒng)防火墻,防止它干涉我們測試赶站。
  5. yum安裝Node.js(同時(shí)安裝npm幔虏,Node’s package manager),我們使用enablerepo來指定在EPEL源中搜索它贝椿,當(dāng)然也可以使用disablerepo來指定不使用那個(gè)源(repository)想括。
  6. 因?yàn)镹PM現(xiàn)在被安裝了,我們使用Ansible 的npm模塊安裝Node.JS工具forever烙博,forever來運(yùn)行我們的app瑟蜈,設(shè)置global為yes,告訴NPM安裝模塊在/usr/lib/node_modules位置渣窜,然后所有的用戶都可以使用它了铺根。

我們已經(jīng)有一個(gè)Node.js app 服務(wù)器了,讓我們部署一個(gè)簡單的Node.js app乔宿,在80端口響應(yīng)HTTP請求

1.2 部署一個(gè)Node.js app

這一步是在我們的服務(wù)器上部署簡單的Node.js app位迂。首先,通過創(chuàng)建一個(gè)新的文件夾详瑞,我們創(chuàng)建一個(gè)簡單的Node.js app掂林,這個(gè)文件夾和你上面的ymal文件處于相同的路徑下面。然后創(chuàng)建新的文件坝橡,app.js泻帮,在這個(gè)文件夾里面,編輯下面的文件

//app.js
// 加載express 模塊.
var express = require('express'),
app = express.createServer();
 
// 響應(yīng)”/”請求為 'Hello World'.
app.get('/', function(req, res){
        res.send('Hello World! Yunzhonge');
});
 
// 像一個(gè)真實(shí)服務(wù)器那樣監(jiān)聽在80端口
app.listen(80);
console.log('Express server started successfully.')

不要擔(dān)心node.js的語法的和我們的案例计寇。我們需要一個(gè)快速的部署案例锣杂,這個(gè)案例可以用Python,Perl饲常,Java蹲堂,PHP或者其他編程語言來寫狼讨,但是因?yàn)镹ode是非常簡單的語言贝淤,運(yùn)行一個(gè)簡單的輕量級(jí)的環(huán)境,它是一個(gè)非常不錯(cuò)的語言來測試你的服務(wù)器政供。

因?yàn)檫@個(gè)小app依賴于Express(一個(gè)簡單的Node的HTTP框架)播聪,我們同樣需要通過一個(gè)package.json文件告訴NPM關(guān)于它的依賴關(guān)系,這個(gè)文件與app.js處于相同的路徑下面。

{
        "name": "examplenodeapp",
        "description": "Example Express Node.js app.",
        "author": "yunzhonghe",
        "dependencies": {
        "express": "3.x.x"
        },
        "engine": "node >= 0.10.6"
}

然后添加下面內(nèi)容到你的playbook里面布隔,拷貝整個(gè)app到這個(gè)服務(wù)器离陶,然后讓npm下載依賴的東西,(這里為express.)

   - name: Ensure Node.js app folder exists.
     file: "path={{ node_apps_location }} state=directory"
 
   - name: Copy example Node.js app to server.
     copy: "src=app dest={{ node_apps_location }}"
 
   - name: Install app dependencies defined in package.json.
     npm: "path={{ node_apps_location }}/app"
  1. 首先我們使用file模塊確保我們安裝的app目錄存在。{{ node_apps_location }}變量可以在vars部分定義衅檀,vars部分位于playbook的頂部招刨。當(dāng)然也可以在inevntory中定義,也可以在運(yùn)行ansible-playbook的時(shí)候定義哀军。
  2. 我們使用Ansible的copy模塊拷貝這整個(gè)app文件夾到測試服務(wù)器沉眶,copy模塊可以聰明的區(qū)分單一的文件和包含文件的目錄打却,然后在目錄中遞歸,就像rsync或scp谎倔。Ansible的copy模塊在單個(gè)文件或少量文件時(shí)候非常好用柳击,但是如果你拷貝大量的文件,嵌套幾層的目錄片习,copy模塊就不能勝任捌肴。這種情形下,如果你想拷貝整個(gè)目錄藕咏,你最好考慮使用synchronize模塊状知,如果你想拷貝一個(gè)歸檔,然后展開它孽查,最好使用unarchive模塊试幽。
  3. 第三步,我們使用npm模塊卦碾,這次除了app的路徑之外沒有額外的參數(shù)铺坞。這告訴NPM來解析package.json文件,然后確保所有的依賴關(guān)系都存在洲胖。
    已經(jīng)都完成了济榨,最后一步是啟動(dòng)這個(gè)app

1.3 運(yùn)行一個(gè)Node.js app

我們現(xiàn)在使用forever來啟動(dòng)這個(gè)app。

   - name: Check list of running Node.js apps.
     command: forever list
     register: forever_list
     changed_when: false
 
   - name: Start example Node.js app.
     command: "forever start {{ node_apps_location }}/app/app.js"
     when: "forever_list.stdout.find('{{ node_apps_location }}/app/app.js') == -1"

在這個(gè)play中绿映,我們做了兩件新的事情擒滑。

  1. register 創(chuàng)建了一個(gè)新的變量,forever_list叉弦,以便于下次task的時(shí)候使用用于判斷是否允運(yùn)行下一個(gè)命令丐一。register用于保存命令的輸出包括標(biāo)準(zhǔn)輸出和錯(cuò)誤輸出,然后賦給變量名淹冰。
  2. changed_when告訴Ansible什么時(shí)候這個(gè)play會(huì)導(dǎo)致改變库车。在這里,forever list命令永遠(yuǎn)都不會(huì)導(dǎo)致服務(wù)器的改變樱拴,因?yàn)槲覀冎付薴alse柠衍。

第二個(gè)play實(shí)際上使用forever啟動(dòng)了這個(gè)app。我們可以啟動(dòng)這個(gè)app通過調(diào)用node {{ node_apps_location }}/app/app.js晶乔,不過這種方式更難控制珍坊。

Forever跟蹤它管理的Node app,然后我們使用Forever的list選項(xiàng)正罢,打印一系列的運(yùn)行app阵漏。我們第一次運(yùn)行這個(gè)playbook時(shí)候,這list明顯是空的,但是判斷為空之后就會(huì)運(yùn)行履怯,如果app正在運(yùn)行川无,我們不會(huì)啟動(dòng)另外一個(gè)實(shí)例了,為了避免這種情形虑乖,我們使用when語句懦趋,指定,當(dāng)app的路徑不在forever list的輸出信息的時(shí)候疹味,我們啟動(dòng)這個(gè)app仅叫。

1.4 Node.js app服務(wù)器總結(jié)。

在這時(shí)候上糙捺,你已經(jīng)完成了playbook诫咱,然后安裝一個(gè)簡單的Node.js app,在80端口響應(yīng)HTTP請求洪灯。
為了運(yùn)行這個(gè)playbook在一個(gè)服務(wù)器上坎缭,使用下面的命令,傳遞node_apps_location變量通過命令

ansible-playbook --extra-vars="node_apps_location=/usr/local/opt/node"

當(dāng)服務(wù)器完成配置和部署服務(wù)器的時(shí)候签钩,在瀏覽器中指定測試服務(wù)器的主機(jī)名查看效果

簡單掏呼,但是有效,我們已經(jīng)在少于50行的YMAL文件中配置了一個(gè)Nodejs應(yīng)用服務(wù)器

到此結(jié)束铅檩,非常感謝朋友們的關(guān)注憎夷。

1.5 問題:

問題1:當(dāng)我在給100臺(tái)服務(wù)器進(jìn)行nodejs app部署的時(shí)候,到20臺(tái)中斷了昧旨,我再重新執(zhí)行拾给,他是一個(gè)怎么個(gè)過程,前面已經(jīng)安裝的軟件包兔沃,進(jìn)行的配置的會(huì)重新的再進(jìn)行執(zhí)行一遍還是跳過呢蒋得?麻煩大牛解答
答:Ansible自身有冪等特性使其能有效保證所有操作的安全可靠性,針對(duì)執(zhí)行失敗的情況會(huì)自動(dòng)在家目錄下生成 對(duì)應(yīng)的錯(cuò)誤服務(wù)器列表 通過 --limit 再次有針對(duì)性的完成剩余工作

問題2: 請問大俠的nodejs 是通過工具部署的? npm 好復(fù)雜啊
哈乒疏,npm的配置是一次性的额衙,初始配置確認(rèn)比較耗時(shí)且麻煩,yum 或 npm 各有優(yōu)劣缰雇,視業(yè)務(wù)而定吧

問題3: --extra-vars= 請問企業(yè)中應(yīng)用的多嗎弃秆?
答:多焚鹊,最少在我們的工作中一直有應(yīng)用骗灶,前幾期的分享大家應(yīng)該也有看到距淫,這個(gè)參數(shù)應(yīng)用的很多省艳。但官網(wǎng)介紹的卻一筆代過邮破。還是建議大家多用

問題4:當(dāng)我通過ansible執(zhí)行任務(wù)的過程中低零,會(huì)出現(xiàn)任務(wù)被長時(shí)間卡主的原因副硅,這一般需要重哪些地方排查呢
答:
很多朋友遇到這個(gè)問題,一直有問爸业,根據(jù)個(gè)人的經(jīng)驗(yàn)建議如下幾個(gè)方面排查:

  1. 確實(shí)當(dāng)前命令執(zhí)行時(shí)間不長其骄,
  2. pong 檢測服務(wù)器存活
  3. 有些命令需連接外網(wǎng)下載更新耗時(shí)較長的可檢查網(wǎng)絡(luò)寬帶情況
  4. -vvv 是非常好的排查方式
  5. 如若卻無解,/etc/ansible/ansible.cfg 中縮短操作執(zhí)行時(shí)長扯旷,等待最終結(jié)束嘗試
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末拯爽,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子钧忽,更是在濱河造成了極大的恐慌毯炮,老刑警劉巖,帶你破解...
    沈念sama閱讀 218,451評(píng)論 6 506
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件耸黑,死亡現(xiàn)場離奇詭異桃煎,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)大刊,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,172評(píng)論 3 394
  • 文/潘曉璐 我一進(jìn)店門为迈,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人缺菌,你說我怎么就攤上這事葫辐。” “怎么了伴郁?”我有些...
    開封第一講書人閱讀 164,782評(píng)論 0 354
  • 文/不壞的土叔 我叫張陵另患,是天一觀的道長。 經(jīng)常有香客問我蛾绎,道長昆箕,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,709評(píng)論 1 294
  • 正文 為了忘掉前任租冠,我火速辦了婚禮鹏倘,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘顽爹。我一直安慰自己纤泵,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,733評(píng)論 6 392
  • 文/花漫 我一把揭開白布镜粤。 她就那樣靜靜地躺著捏题,像睡著了一般。 火紅的嫁衣襯著肌膚如雪肉渴。 梳的紋絲不亂的頭發(fā)上公荧,一...
    開封第一講書人閱讀 51,578評(píng)論 1 305
  • 那天,我揣著相機(jī)與錄音同规,去河邊找鬼循狰。 笑死窟社,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的绪钥。 我是一名探鬼主播灿里,決...
    沈念sama閱讀 40,320評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼程腹!你這毒婦竟也來了匣吊?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,241評(píng)論 0 276
  • 序言:老撾萬榮一對(duì)情侶失蹤寸潦,失蹤者是張志新(化名)和其女友劉穎色鸳,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體甸祭,經(jīng)...
    沈念sama閱讀 45,686評(píng)論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡缕碎,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,878評(píng)論 3 336
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了池户。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片咏雌。...
    茶點(diǎn)故事閱讀 39,992評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖校焦,靈堂內(nèi)的尸體忽然破棺而出赊抖,到底是詐尸還是另有隱情,我是刑警寧澤寨典,帶...
    沈念sama閱讀 35,715評(píng)論 5 346
  • 正文 年R本政府宣布氛雪,位于F島的核電站,受9級(jí)特大地震影響耸成,放射性物質(zhì)發(fā)生泄漏报亩。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,336評(píng)論 3 330
  • 文/蒙蒙 一井氢、第九天 我趴在偏房一處隱蔽的房頂上張望弦追。 院中可真熱鬧,春花似錦花竞、人聲如沸劲件。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,912評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽零远。三九已至,卻和暖如春厌蔽,著一層夾襖步出監(jiān)牢的瞬間牵辣,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,040評(píng)論 1 270
  • 我被黑心中介騙來泰國打工躺枕, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留服猪,地道東北人供填。 一個(gè)月前我還...
    沈念sama閱讀 48,173評(píng)論 3 370
  • 正文 我出身青樓拐云,卻偏偏與公主長得像罢猪,于是被迫代替她去往敵國和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子叉瘩,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,947評(píng)論 2 355

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

  • Node.js是目前非成排粒火熱的技術(shù),但是它的誕生經(jīng)歷卻很奇特薇缅。 眾所周知危彩,在Netscape設(shè)計(jì)出JavaScri...
    Myselfyan閱讀 4,072評(píng)論 2 58
  • Node.js是目前非常火熱的技術(shù)泳桦,但是它的誕生經(jīng)歷卻很奇特汤徽。 眾所周知,在Netscape設(shè)計(jì)出JavaScri...
    w_zhuan閱讀 3,615評(píng)論 2 41
  • 1 Node.js模塊的實(shí)現(xiàn) 之前在網(wǎng)上查閱了許多介紹Node.js的文章,可惜對(duì)于Node.js的模塊機(jī)制大都著...
    zlx_2017閱讀 1,243評(píng)論 0 1
  • 1 Node.js模塊的實(shí)現(xiàn)# 之前在網(wǎng)上查閱了許多介紹Node.js的文章,可惜對(duì)于Node.js的模塊機(jī)制大都...
    七寸知架構(gòu)閱讀 2,062評(píng)論 1 50
  • 逆風(fēng)飛翔的小蕊閱讀 566評(píng)論 0 0