Docker-Nginx

���Ľ�������л�����Ķ�

学习步骤如下: 1. 建立docker容器运行程序 2. 用上面建立的docker容器加上Nginx实现简单的负载均衡(与docker本身无关) 3. 建立基础仓库到阿里云 4. 梳理宿主机与容器间的两个Nginx关系 简单说下docker docker 是一种新兴的虚拟化方式,跟传统的虚拟化方式相比具有众多优势 更高效的利用系统资源,容器不需要进行硬件虚拟化已经运行完整的操作系统等额外开销,所以对系统资源的利用率比较高; 启动速度更快,原因和上面差不多; 一致的运行环境,一般称需要经过开发环境、测试环境、生产环境,但是无法确保所有的环境都是一致的, 所有就会出现同一段代码在不同环境输出的结果不一致,docker镜像提供了相同的运行环境(出内核外),可以避免上述问题的发生; 在程序交付的运维时,只需要提供Dockerfile文件即可实现快速部署 方便迁移,由于每个容器都是一个独立运行环境,和宿主机没有直接关系; docker包含三个概念: 1. 镜像(image) 2. 容器(container) 3. 仓库(repository) 这三个概念后面用到在说,方便理解 一、建立docker容器运行程序 这是我做的第一个比较简单,首先建立的一个简单的express项目,在项目的根目录建立了一个Dockerfile文件(注意第一个字母大写),后面调用run指令的时候docker会默认寻找这个文件,当然这个文件名也可以修改,但是需要得修改相应配置,在Dockerfile 中写入下面代码:

1
2
3
4
5
6
7
FROM node:slim
ENV HTTP_PORT 8000
COPY . /app
WORKDIR /app
RUN npm install --registry=https://registry.npm.taobao.org
EXPOSE 8000
CMD [ "npm", "start" ]

FROM: 后面跟的是镜像来源,也就是基于那个镜像建立的镜像, 其中node是镜像名称,slim 是镜像版本号,这个node是官方给的基础版本,官网的基础镜像还有很多,点击这里查看更多, 当然还有其他人自定义的优质镜像这里就罗列了, ENV 指的是运行环境,一般程序都会分为development、production 等,我这里直接指定了端口号 COPY 复制,中间有个点 指的是当前目录,复制到/app目录,注意这里不是复制到真实的目录而已复制到容器的目录,所以在真实目录是看不到这个文件夹的 WORKDIR 指定工作目录 RUN npm 安装依赖包 并切换至淘宝源 EPOSE 容器输出端口 CMD 执行启动命令 在根项目根目录下(也是Dockerfile 所在目录)执行 下面代码建立自己的镜像 docker build -t myexpress . build 是建立镜像指令,-t 是添加镜像标签 注意后面有个空格和点,这里的点指的是当前目录,执行完上面命令之后再执行 docker images 就可以看到当前的拥有的镜像了,在你自定义myexpress的镜像之外 还多出了node的镜像,这是因为我们的镜像是建立在node镜像基础之上的,下次在建立依赖node镜像时,就不需要再次下载node镜像了,因为重复利用了,节省的资源 建立完镜像后 ,我们就开始生成容器了,镜像和容器的关系就像是 类和实例的关系,一个镜像可以生成多个容器,执行下方指令生成容器: docker run –name mycontainername -d -p 80:8000 myexpress name 是给当前容器命名 d 是后端运行 p 80是容器端口 8000是映射到主机的端口 myexpress 是前面建立的进行名称 项目已经运行起来,直接访问宿主机ip 即可看到项目主页 二、用上面建立的docker容器加上Nginx实现简单的负载均衡 这个部分的出现纯属意外和docker没有直接关系,我只是刚好看到这里就记录下来 在Nginx的配置文件 http下添加 upstream 代码如下:

1
2
3
4
upstream zmb {
server 127.0.0.1:8080;
server 127.0.0.1:8081;
}

zmb随便取的只是个代号,后面可以添加weight属性标识权重 然后在server 下location去添加配置 如下:

1
2
3
location / {
proxy_pass http://zmb;
}

注意这里的两个zmb 必须保持一致 这样在每次请求sever端口是都会循环访问8080和8081端口,若有一个失败则直接访问下一个 三、建立基础仓库到阿里云 这里前提是必须要有一个阿里云账号,将代码托管到阿里云自己仓库 https://code.aliyun.com, 我们建立一个 空项目 项目里面只有一个Dockerfile 文件并把这个项目同步到自己的仓库,Dockerfile的配置如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
#version 1.0
#Base image
FROM centos
#MAINTAINER
MAINTAINER zyb
WORKDIR /usr/local/src
#download soft
RUN yum install -y gcc make gcc-c++ openssl-devel wget zlib* perl perl-devel

#pcre
WORKDIR /usr/local/src
RUN wget https://ncu.dl.sourceforge.net/project/pcre/pcre/8.41/pcre-8.41.tar.gz
RUN tar -zxf pcre-8.41.tar.gz
WORKDIR pcre-8.41
RUN ./configure
RUN make && make install

#zib-1.2.11
WORKDIR /usr/local/src
RUN wget http://www.zlib.net/zlib-1.2.11.tar.gz
RUN tar -zxf zlib-1.2.11.tar.gz
WORKDIR zlib-1.2.11
RUN ./configure
RUN make && make install

#Openssl
WORKDIR /usr/local/src
RUN wget https://www.openssl.org/source/openssl-1.0.2l.tar.gz
RUN tar -zxf openssl-1.0.2l.tar.gz
WORKDIR openssl-1.0.2l
RUN ./config -fPIC --prefix=/usr/local/openssl/ enable-shared
RUN make depend
RUN make && make install

#nginx
WORKDIR /usr/local/src
RUN wget http://nginx.org/download/nginx-1.13.6.tar.gz
RUN tar -zxf nginx-1.13.6.tar.gz
WORKDIR nginx-1.13.6
RUN ./configure --sbin-path=/usr/local/nginx/nginx \
--conf-path=/usr/local/nginx/nginx.conf \
--pid-path=/usr/local/nginx/nginx.pid \
--with-http_ssl_module \
--with-pcre=/usr/local/src/pcre-8.41 \
--with-zlib=/usr/local/src/zlib-1.2.11 \
--with-openssl=/usr/local/src/openssl-1.0.2l \
--with-stream
RUN make && make install

#nodejs
WORKDIR /usr/local/src
RUN wget https://nodejs.org/dist/v8.8.1/node-v8.8.1.tar.gz
RUN tar -zxf node-v8.8.1.tar.gz
WORKDIR node-v8.8.1
RUN ./configure
RUN make install
RUN npm config set registry https://registry.npm.taobao.org
RUN rm -rf /usr/local/src/*

主要是在centos镜像基础上添加了Nginx和node 同步上去之后再 去阿里云上点击 容器镜像服务 功能, 添加镜像仓库,代码源设置为阿里云code,选取命名空间,选择刚才同步的代码仓库等,构建设置 勾选 在代码更新时自动构建, 添加完成之后,列表也点击设置–> 构建–> 立即构建,第一次构建需要编译时间比较长,到此一个基础的centos+Nginx+node的镜像已经构建完成了,列表页有个仓库地址 后面引用项目就FROM该地址即可。 四、梳理宿主机与容器间的两个Nginx关系 上面示例中容器中有个Nginx,一般容器外也会有个Nginx,那么他们两个之间有什么关系或者说怎么个运行步骤呢? 在一个宿主机中一般会有多个容器,容器外的Nginx根据端口号分发给各个容器的,容器Dockerfile文件中espose 可以设置暴露多个端口号,容器在构建时一般会映射端口号(-p 容器端口号和主机端口号),这里容器的端口号应该是上面expose 中的一个,主机端口号应该和内部Nginx接受端口相对应,内部的Nginx再讲端口映射到我们项目程序的端口,这样看来内部的Nginx好像没有多大作用(容器可以直接访问主程序的),我是这样认为的,因为在这个示例中外部是有配置Nginx的,如果外部要是什么都没有配置,也可以直接构建项目,因为我们镜像内部包含有Nginx做映射; 也就是说流程应该是这样的 client 访问宿主机 经过外部的Nginx的映射,到相应的容器(若espose没有匹配到则无法访问),容器接受到请求根据端口号经过内部Nginx的映射到我们的主程序中。

0%