本文会通过三个简单的demo,演示如何通过docker部署node集群。
如果想学习docker,官方文档是一个不错的入门指引,或者可以看这个gitbook。
一、部署node容器
首先准备一个node服务demo,代码如下:
const Koa = require('koa');
const app = new Koa();
app.use(async ctx => {
ctx.body = 'Hello World';
});
app.listen(8080);
部署node服务
制作自己的node服务镜像,最简单的方式就是基于已有的node镜像,在此基础上,添加自己的内容,可以通过Dockerfile描述自己的node镜像,内容如下:
FROM node:8.9.1
# 复制当前代码到指定目录下
ADD . /home/app
WORKDIR /home/app
RUN npm install
EXPOSE 8080
CMD ["npm", "run", "dev"]
有了镜像文件之后,可以通过docker build
构建镜像:
docker build -t node-demo .
# -t 表示定义镜像名
查看当前构建的镜像:
docker images
通过镜像运行容器:
docker run -d -p 8080:8080 node-demo
# -d 表示后台运行
查看运行中容器信息:
docker ps
查看容器运行日志:
docker logs xxx
# xxx 为容器id
暂停容器:
docker container stop xxx
因为镜像底层是一个linux镜像,所以可以连接上容器bash:
docker exec -i -t xxx bash
二、部署node、redis服务
在第一步代码的基础上,我们使用node连接一个redis,模拟一个访客计数的功能,修改后的node代码如下:
const Koa = require('koa');
const bluebird = require("bluebird");
const redis = require("redis");
bluebird.promisifyAll(redis.RedisClient.prototype);
bluebird.promisifyAll(redis.Multi.prototype);
const app = new Koa();
// 注意这里的host被指定为 redis,这是docker compose提供的功能
let host = 'redis';
let port = '6379';
let client = redis.createClient({
host,
port
});
app.use(async ctx => {
if (ctx.path == '/incr') {
let num = await client.getAsync('num');
num++;
client.set('num', num, redis.print);
return ctx.body = `num is ${num}`;
}
ctx.body = 'Hello World';
});
app.listen(8080);
node服务需要连接redis服务,docker提供了compose工具简化了容器间通信,要使用compose功能,需要定义描述文件docker-compose.yml:
version: '3'
services:
web:
build: .
ports:
- "8080:8080"
redis:
image: "redis:alpine"
这里描述了两个容器web和redis,分别对应node和redis。
然后通过docker-compose
启动容器,默认如果没有构建镜像,会先构建或者pull镜像:
docket-compose up -d
查看容器运行情况:
docker-compose ps
暂停容器:
docker-compose stop
三、部署node集群
最后例子是启动多个node容器,构成集群,然后访问同一个redis:
利用docker提供的实例扩展,其实很容易做到,只要修改docker-compose.yml如下:
version: '3'
services:
web:
image: node-demo
deploy:
replicas: 5
resources:
limits:
cpus: "0.1"
memory: 50M
ports:
- "8080:8080"
redis:
image: "redis:alpine"
唯一的区别就是添加了deploy
声明,指定是node实例数量和资源情况。
对于真正的集群部署,docker提供了swarm功能,swarm功能很强大,可以管理跨机器部署,这里就只用到最简单的实例扩展。
首先创建集群:
docker swarm init
然后部署集群
docker stack deploy -c docker-compose.yml node-swarm
查看集群运行情况
docker service ls
然后查看容器运行情况
docker container ls
可以看到当前有6个容器在运行,一个redis容器,五个node容器。