真实的国产乱ⅩXXX66竹夫人,五月香六月婷婷激情综合,亚洲日本VA一区二区三区,亚洲精品一区二区三区麻豆

成都創(chuàng)新互聯(lián)網(wǎng)站制作重慶分公司

當(dāng)Node.js遇見(jiàn)Docker

Node.js Best Practices - How to Become a Better Developer in 2017提到的幾點(diǎn),我們Fundebug深有同感:

創(chuàng)新互聯(lián)服務(wù)項(xiàng)目包括赤城網(wǎng)站建設(shè)、赤城網(wǎng)站制作、赤城網(wǎng)頁(yè)制作以及赤城網(wǎng)絡(luò)營(yíng)銷(xiāo)策劃等。多年來(lái),我們專(zhuān)注于互聯(lián)網(wǎng)行業(yè),利用自身積累的技術(shù)優(yōu)勢(shì)、行業(yè)經(jīng)驗(yàn)、深度合作伙伴關(guān)系等,向廣大中小型企業(yè)、政府機(jī)構(gòu)等提供互聯(lián)網(wǎng)行業(yè)的解決方案,赤城網(wǎng)站推廣取得了明顯的社會(huì)效益與經(jīng)濟(jì)效益。目前,我們服務(wù)的客戶(hù)以成都為中心已經(jīng)輻射到赤城省份的部分城市,未來(lái)相信會(huì)繼續(xù)擴(kuò)大服務(wù)區(qū)域并繼續(xù)獲得客戶(hù)的支持與信任!

  • 使用ES6
  • 使用Promise
  • 使用LTS
  • 使用Docker
  • ...

想必大家都知道ES6,Promise以及LTS,那Docker是啥玩意?。糠镹ode文檔也沒(méi)見(jiàn)蹤跡啊!
當(dāng)Node.js遇見(jiàn)Docker

GitHub倉(cāng)庫(kù):Fundebug/nodejs-docker

什么是Docker?

Docker是最流行的的容器工具,沒(méi)有之一。本文并不打算深入介紹Docker,不過(guò)可以從幾個(gè)簡(jiǎn)單的角度來(lái)理解Docker。

從進(jìn)程的角度理解Docker

在Linux中,所有的進(jìn)程構(gòu)成了一棵樹(shù)??梢允褂胮stree命令進(jìn)行查看:

pstree
init─┬─VBoxService───7*[{VBoxService}]
     ├─acpid
     ├─atd
     ├─cron
     ├─dbus-daemon
     ├─dhclient
     ├─dockerd─┬─docker-containe─┬─docker-containe─┬─redis-server───2*[{redis-server}]
     │         │                 │                 └─8*[{docker-containe}]
     │         │                 ├─docker-containe─┬─mongod───16*[{mongod}]
     │         │                 │                 └─8*[{docker-containe}]
     │         │                 └─11*[{docker-containe}]
     │         └─13*[{dockerd}]
     ├─6*[getty]
     ├─influxd───9*[{influxd}]
     ├─irqbalance
     ├─puppet───{puppet}
     ├─rpc.idmapd
     ├─rpc.statd
     ├─rpcbind
     ├─rsyslogd───3*[{rsyslogd}]
     ├─ruby───{ruby}
     ├─sshd─┬─sshd───sshd───zsh───pstree
     │      ├─sshd───sshd───zsh
     │      └─sshd───sshd───zsh───mongo───2*[{mongo}]
     ├─systemd-logind
     ├─systemd-udevd
     ├─upstart-file-br
     ├─upstart-socket-
     └─upstart-udev-br

可知,init進(jìn)程為所有進(jìn)程的根(root),其PID為1。

Docker將不同應(yīng)用的進(jìn)程隔離了起來(lái),這些被隔離的進(jìn)程就是一個(gè)個(gè)容器。隔離是基于兩個(gè)Linux內(nèi)核機(jī)制實(shí)現(xiàn)的,Namesapce和Cgroups。

Namespace可以從UTD、IPC、PID、Mount,User和Network的角度隔離進(jìn)程。比如,不同的進(jìn)程將擁有不同PID空間,這樣容器中的進(jìn)程將看不到主機(jī)上的進(jìn)程,也看不到其他容器中的進(jìn)程。這與Node.js中模塊化以隔離變量的命名空間的思想是異曲同工的。

通過(guò)Cgroups,可以限制進(jìn)程對(duì)CPU,內(nèi)存等資源的使用。簡(jiǎn)單地說(shuō),我們可以通過(guò)Cgroups指定容器只能使用1G內(nèi)存。

從進(jìn)程角度理解Docker,那每一個(gè)Docker容器就是被隔離的進(jìn)程及其子進(jìn)程。上文pstree的輸出中可以分辨出2個(gè)容器: MongoDB和redis。

從文件的角度理解Docker

基于Namespace與Cgroups的容器工具其實(shí)早已存在,例如Linux-VServer,OpenVZ,LXC。然而,真正引爆容器技術(shù)的卻是后來(lái)者Docker。為什么呢?個(gè)人覺(jué)得是因?yàn)?strong>Docker鏡像以及Dockerfile。

在Linux中,一切皆文件,進(jìn)程的運(yùn)行離不開(kāi)各種各樣的文件。跑一個(gè)簡(jiǎn)單的Node.js程序,傳統(tǒng)的做法是手動(dòng)安裝各種依賴(lài)然后運(yùn)行;而Docker則是將所有依賴(lài)(包括操作系統(tǒng),Node,NPM模塊,源代碼)打包到一個(gè)Docker鏡像中,然后基于這個(gè)鏡像運(yùn)行容器。

Docker鏡像可以通過(guò)Docker倉(cāng)庫(kù)共享給其他人,這樣他們只需要下載鏡像即可運(yùn)行程序。想象一下,當(dāng)我們需要在另一臺(tái)主機(jī)(比如生產(chǎn)服務(wù)器,新同事的機(jī)器)上運(yùn)行一個(gè)Node.js應(yīng)用,僅僅需要下載對(duì)應(yīng)的Docker鏡像就可以了,是不是很方便呢?

Docker鏡像可以通過(guò)文本文件,即Dockerfile進(jìn)行定義。不妨看一個(gè)簡(jiǎn)單的例子(由于不可抗力,這個(gè)Dockerfile構(gòu)建大概會(huì)失敗,僅作為參考):

# 基于Ubuntu
FROM ubuntu

# 安裝Node.js與NPM
RUN apt-get update && apt-get -y install nodejs npm

# 安裝NPM模塊:Express
RUN npm install express

# 添加源代碼
ADD app.js /

其中,FROM,RUNADD為Dockerfile命令。結(jié)合注釋?zhuān)揇ockerfile的含義非常直白。基于這個(gè)Dockerfile,使用docker build命令就可以構(gòu)建對(duì)應(yīng)的Docker鏡像?;谶@個(gè)Docker鏡像,就可以運(yùn)行Docker容器來(lái)執(zhí)行app.js:

var express = require("express");
var app = express();

app.get("/", function(req, res)
{
    res.send("Hello Fundebug!\n");
});

app.listen(3000);

Dockerfile實(shí)際上是將Docker鏡像代碼化了,另一方面也是將安裝依賴(lài)的過(guò)程代碼化了,于是我們就可以像管理源碼一樣使用git對(duì)Dockerfile進(jìn)行版本管理。

為啥用Docker?

當(dāng)你的系統(tǒng)越來(lái)越復(fù)雜的時(shí)候,你會(huì)發(fā)現(xiàn)Docker的價(jià)值。

從應(yīng)用架構(gòu)角度理解Docker

剛開(kāi)始,你只需要寫(xiě)一個(gè)Node.js程序,掛載一個(gè)靜態(tài)網(wǎng)站;然后,你做了一個(gè)用戶(hù)賬號(hào)系統(tǒng),這時(shí)需要數(shù)據(jù)庫(kù)了,比如說(shuō)MySQL; 后來(lái),為了提升性能,你引入了Memcached緩存;終于有一天,你決定把前后端分離,這樣可以提高開(kāi)發(fā)效率;當(dāng)用戶(hù)越來(lái)越多,你又不得不使用Nginx做反向代理; 對(duì)了,隨著功能越來(lái)越多,你的應(yīng)用依賴(lài)也會(huì)越來(lái)越多...總之,你的應(yīng)用架構(gòu)只會(huì)越來(lái)越復(fù)雜。不同的組件的安裝,配置與運(yùn)行步驟各不相同,于是你不得不寫(xiě)一個(gè)很長(zhǎng)的文檔給新同事,只為了讓他搭建一個(gè)開(kāi)發(fā)環(huán)境。

使用Docker的話(huà),你可以為不同的組件逐一編寫(xiě)Dockerfile,分別構(gòu)建鏡像,然后運(yùn)行在各個(gè)容器中。這樣做,將復(fù)雜的架構(gòu)統(tǒng)一了,所有組件的安裝和運(yùn)行步驟統(tǒng)一為幾個(gè)簡(jiǎn)單的命令:

  • 構(gòu)建Docker鏡像: docker build
  • 上傳Docker鏡像: docker push
  • 下載Docker鏡像: docker pull
  • 運(yùn)行Docker容器: docker run
從應(yīng)用部署角度理解Docker

通常,你會(huì)有開(kāi)發(fā),測(cè)試生產(chǎn)服務(wù)器,對(duì)于某些應(yīng)用,還會(huì)需要進(jìn)行構(gòu)建。不同步驟的依賴(lài)會(huì)有一些不同,并且在不同的服務(wù)器上執(zhí)行。如果手動(dòng)地在不同的服務(wù)器上安裝依賴(lài),是件很麻煩的事情。比如說(shuō),當(dāng)你需要為Node.js應(yīng)用添加一個(gè)新的npm模塊,或者升級(jí)一下Node.js,是不是得重復(fù)操作很多次?友情提示一下,手動(dòng)敲命令是極易出錯(cuò)的,有些失誤會(huì)導(dǎo)致致命的后果(參考最近Gitlab誤刪數(shù)據(jù)庫(kù)與AWS的S3故障)。

如果使用Docker的話(huà),開(kāi)發(fā)、構(gòu)建、測(cè)試、生產(chǎn)將全部在Docker容器中執(zhí)行,你需要為不同步驟編寫(xiě)不同的Dockerfile。當(dāng)依賴(lài)變化時(shí),僅需要稍微修改Dockerfile即可。結(jié)合構(gòu)建工具Jenkins,就可以將整個(gè)部署流程自動(dòng)化。

另一方面,Dockerfile將Docker鏡像描述得非常精準(zhǔn),能夠保證很強(qiáng)的一致性。比如,操作系統(tǒng)的版本,Node.js的版本,NPM模塊的版本等。這就意味著,在本地開(kāi)發(fā)環(huán)境運(yùn)行成功的鏡像,在構(gòu)建測(cè)試、生產(chǎn)環(huán)境中也沒(méi)有問(wèn)題。還有,不同的Docker容器是依賴(lài)于不同的Docker鏡像,這樣他們互不干擾。比如,兩個(gè)Node.js應(yīng)用可以分別使用不同版本的Node.js。

從集群管理角度理解Docker

架構(gòu)規(guī)模越來(lái)越大的時(shí)候,你有必要引入集群了。這就意味著,服務(wù)器由1臺(tái)變成了多臺(tái),同一個(gè)應(yīng)用需要運(yùn)行多個(gè)備份來(lái)分擔(dān)負(fù)載。當(dāng)然,你可以手動(dòng)對(duì)集群的功能進(jìn)行劃分: Nginx服務(wù)器,Node.js服務(wù)器,MySQL服務(wù)器,測(cè)試服務(wù)器,生產(chǎn)服務(wù)器...這樣做的好處是簡(jiǎn)單粗暴;也可以說(shuō)財(cái)大氣粗,因?yàn)橘Y源閑置會(huì)非常嚴(yán)重。還有一點(diǎn),每次新增節(jié)點(diǎn)的時(shí)候,你就不得不花大量時(shí)間進(jìn)行安裝與配置,這其實(shí)是一種低效的重復(fù)勞動(dòng)。

下載Docker鏡像之后,Docker容器可以運(yùn)行在集群的任何一個(gè)節(jié)點(diǎn)。一方面,各個(gè)組件可以共享主機(jī),且互不干擾;另一方面,也不需要在集群的節(jié)點(diǎn)上安裝和配置任何組件。至于整個(gè)Docker集群的管理,業(yè)界有很多成熟的解決方案,例如Mesos,Kubernetes與Docker Swarm。這些集群系統(tǒng)提供了調(diào)度,服務(wù)發(fā)現(xiàn)負(fù)載均衡等功能,讓整個(gè)集群變成一個(gè)整體。

如何用Docker?

編寫(xiě)Dockerfile

正確的Dockerfile是這樣的:

# 使用DaoCloud的Ubuntu鏡像
FROM daocloud.io/library/ubuntu:14.04

# 設(shè)置鏡像作者
MAINTAINER Fundebug 

# 設(shè)置時(shí)區(qū)
RUN sudo sh -c "echo 'Asia/Shanghai' > /etc/timezone" && \
    sudo dpkg-reconfigure -f noninteractive tzdata

# 使用阿里云的Ubuntu鏡像
RUN echo '\n\
deb http://mirrors.aliyun.com/ubuntu/ trusty main restricted universe multiverse\n\
deb http://mirrors.aliyun.com/ubuntu/ trusty-security main restricted universe multiverse\n\
deb http://mirrors.aliyun.com/ubuntu/ trusty-updates main restricted universe multiverse\n\
deb http://mirrors.aliyun.com/ubuntu/ trusty-proposed main restricted universe multiverse\n\
deb http://mirrors.aliyun.com/ubuntu/ trusty-backports main restricted universe multiverse\n\
deb-src http://mirrors.aliyun.com/ubuntu/ trusty main restricted universe multiverse\n\
deb-src http://mirrors.aliyun.com/ubuntu/ trusty-security main restricted universe multiverse\n\
deb-src http://mirrors.aliyun.com/ubuntu/ trusty-updates main restricted universe multiverse\n\
deb-src http://mirrors.aliyun.com/ubuntu/ trusty-proposed main restricted universe multiverse\n\
deb-src http://mirrors.aliyun.com/ubuntu/ trusty-backports main restricted universe multiverse\n'\
> /etc/apt/sources.list

# 安裝node v6.10.1
RUN sudo apt-get update && sudo apt-get install -y wget

# 使用淘寶鏡像安裝Node.js v6.10.1
RUN wget https://npm.taobao.org/mirrors/node/v6.10.1/node-v6.10.1-linux-x64.tar.gz && \
    tar -C /usr/local --strip-components 1 -xzf node-v6.10.1-linux-x64.tar.gz && \
    rm node-v6.10.1-linux-x64.tar.gz 

WORKDIR /app

# 安裝npm模塊
ADD package.json /app/package.json

# 使用淘寶的npm鏡像
RUN npm install --production -d --registry=https://registry.npm.taobao.org

# 添加源代碼
ADD . /app

# 運(yùn)行app.js
CMD ["node", "/app/app.js"]

有幾點(diǎn)值得注意的地方:

  • 使用國(guó)內(nèi)DaoCloud的Docker倉(cāng)庫(kù),阿里云的ubuntu鏡像以及淘寶的npm鏡像,否則會(huì)出事情的;
  • 將時(shí)區(qū)設(shè)為Asia/Shanghai,否則日志的時(shí)間會(huì)不大對(duì)勁;
  • 使用.dockerignore忽略不需要添加到Docker鏡像的文件和目錄,其語(yǔ)法與.gitigore一致;

更重要的一點(diǎn)是,package.json需要單獨(dú)添加。Docker在構(gòu)建鏡像的時(shí)候,是一層一層構(gòu)建的,僅當(dāng)這一層有變化時(shí),重新構(gòu)建對(duì)應(yīng)的層。如果package.json和源代碼一起添加到鏡像,則每次修改源碼都需要重新安裝npm模塊,這樣木有必要。所以,正確的順序是: 添加package.json;安裝npm模塊;添加源代碼。

構(gòu)建Docker鏡像

使用docker build命令構(gòu)建Docker鏡像

sudo docker build -t fundebug/nodejs .

其中,-t選項(xiàng)用于指定鏡像的名稱(chēng)。

使用docker images命令查看Docker鏡像

sudo docker images
REPOSITORY                    TAG                 IMAGE ID            CREATED             SIZE
fundebug/nodejs               latest              64530ce811a1        32 minutes ago      266.4 MB
daocloud.io/library/ubuntu    14.04               b969ab9f929b        9 weeks ago         188 MB

可知,fundebug/nodejs鏡像的大小為266.4MB,在ubuntu鏡像的基礎(chǔ)上增加了80MB左右。

運(yùn)行Docker容器

使用docker run命令運(yùn)行Docker容器

sudo docker run -d --net=host --name=hello-fundebug fundebug/nodejs

其中,-d選項(xiàng)表示容器在后臺(tái)運(yùn)行;--net選項(xiàng)指定容器的網(wǎng)絡(luò)模式,host表示與主機(jī)共享網(wǎng)絡(luò);--name指定了容器的名稱(chēng)。

使用docker ps命令查看Docker容器

sudo docker ps
CONTAINER ID        IMAGE                             COMMAND                  CREATED             STATUS              PORTS               NAMES
e8eb5473970c        fundebug/nodejs                   "node /app/app.js"       37 minutes ago      Up 37 minutes                           hello-

可知,COMMAND為"node /app/app.js",表示容器中運(yùn)行的命令。這是我們?cè)貲ockerfile中使用CMD指定的。不妨使用docker exec命令在容器內(nèi)執(zhí)行ps命令查看容器內(nèi)的進(jìn)程

sudo docker exec hello-fundebug ps -f
UID        PID  PPID  C STIME TTY          TIME CMD
root         1     0  0 15:14 ?        00:00:00 node /app/app.js

可知,容器內(nèi)的1號(hào)進(jìn)程即為node進(jìn)程node /app/app.js。在Linux中,PID為1進(jìn)程按說(shuō)是唯一的,即init進(jìn)程。但是,容器使用了內(nèi)核的Namespace機(jī)制,為容器創(chuàng)建了獨(dú)立的PID空間,因此容器中也有1號(hào)進(jìn)程。

測(cè)試

使用curl命令訪(fǎng)問(wèn):

curl localhost:3000
Hello Fundebug!

是否用Docker?

一方面,使用Docker能夠帶來(lái)很大益處;另一方面,引入Docker必然會(huì)有很多挑戰(zhàn),需要熟悉Docker才能應(yīng)對(duì)自如。想必這是一個(gè)艱難的決定。如果從長(zhǎng)遠(yuǎn)的角度來(lái)看,Docker正在成為應(yīng)用開(kāi)發(fā),部署,發(fā)布的標(biāo)準(zhǔn)技術(shù),也許我們不得不用開(kāi)放的心態(tài)對(duì)待它。

作為Node.js開(kāi)發(fā)者,真正理解Docker可能需要一些時(shí)間,但是它可以給你帶來(lái)很多便利。

參考鏈接

  • DOCKER基礎(chǔ)技術(shù):LINUX NAMESPACE(上)
  • DOCKER基礎(chǔ)技術(shù):LINUX NAMESPACE(下)
  • DOCKER基礎(chǔ)技術(shù):LINUX CGROUP
  • 從GITLAB誤刪除數(shù)據(jù)庫(kù)想到的
  • AWS 的 S3 故障回顧和思考

關(guān)于Fundebug

Fundebug專(zhuān)注于JavaScript、微信小程序、微信小游戲、支付寶小程序、React Native、Node.js和Java實(shí)時(shí)BUG監(jiān)控。 自從2016年雙十一正式上線(xiàn),F(xiàn)undebug累計(jì)處理了7億+錯(cuò)誤事件,得到了Google、360、金山軟件、百姓網(wǎng)等眾多知名用戶(hù)的認(rèn)可。歡迎免費(fèi)試用!

當(dāng)Node.js遇見(jiàn)Docker

版權(quán)聲明

轉(zhuǎn)載時(shí)請(qǐng)注明作者Fundebug以及本文地址:

https://blog.fundebug.com/2017/03/27/nodejs-docker/


分享文章:當(dāng)Node.js遇見(jiàn)Docker
分享路徑:http://weahome.cn/article/geoohp.html

其他資訊

在線(xiàn)咨詢(xún)

微信咨詢(xún)

電話(huà)咨詢(xún)

028-86922220(工作日)

18980820575(7×24)

提交需求

返回頂部