实战docker,构建nginx反向代理tomcat,学习link和docker-compose

上一次我们学习了制作Dockerfile构建定制的tomcat镜像文件,今天我们学习构建一个nginx镜像文件,然后通过docker-compse将nginx和tomcat一起启动,最终达到的效果如下图所示,应用app部署在两个tomcat上,用户访问的是Nginx所在的机器,Nginx会将请求转发到Tomcat001或者Tomcat002上:

Nginx实现负载均衡是通过配置nginx.conf来实现的,nginx.conf的全部内容如下:

user  nginx;
worker_processes  1;

error_log  /var/log/nginx/error.log warn;
pid        /var/run/nginx.pid;


events {
    worker_connections  1024;
}


http {
    include       /etc/nginx/mime.types;
    default_type  application/octet-stream;

    log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
                      '$status $body_bytes_sent "$http_referer" '
                      '"$http_user_agent" "$http_x_forwarded_for"';

    access_log  /var/log/nginx/access.log  main;

    sendfile        on;
    #tcp_nopush     on;

    keepalive_timeout  65;

    #gzip  on;

    #include /etc/nginx/conf.d/*.conf;

    upstream tomcat_client {
         server t01:8080 weight=1;
         server t02:8080 weight=1;
    } 

    server {
        server_name "";
        listen 80 default_server;
        listen [::]:80 default_server ipv6only=on;

        location / {
            proxy_pass http://tomcat_client;
            proxy_redirect default;
            proxy_set_header Host $host;
            proxy_set_header X-Real-IP $remote_addr;
        }
    }
}

可以看到,通过server节点的配置实现了监听80端口,“proxy_pass http://tomcat_client;“表示对请求的处理交给了tomcat_client,而tomcat_client的具体配置:

upstream tomcat_client {
         server t01:8080 weight=1;
         server t02:8080 weight=1;
    } 

即交给了url为t01:8080和t02:8080这两个server,并且每个server处理的权重都是1。(t01:8080和t02:8080究竟是什么?其实这是个别名,和link参数中的别名对应,这个咱们后面用到link的时候再讲) nginx的配置就这些了,接下来我们看看如何制作nginx的镜像文件,也就是Dockerfile的具体内容:

# First docker file from bolingcavalry
# VERSION 0.0.1
# Author: bolingcavalry

#基础镜像
FROM nginx:stable

#作者
MAINTAINER BolingCavalry <zq2599@gmail.com>

#定义工作目录
ENV WORK_PATH /etc/nginx

#定义conf文件名
ENV CONF_FILE_NAME nginx.conf

#删除原有配置文件
RUN rm $WORK_PATH/$CONF_FILE_NAME

#复制新的配置文件
COPY ./$CONF_FILE_NAME $WORK_PATH/

#给shell文件赋读权限
RUN chmod a+r $WORK_PATH/$CONF_FILE_NAME

如上所示,Dockerfile文件非常简单,就是把原有系统中的nginx.conf文件删掉,换成我们刚才自己做的文件就行了。

现在我们新建个目录image_nginx,这个目录下只有两个文件,nginx.conf和Dockerfile,如下图:

打开终端,进入此目录,执行命令行:

docker build -t bolingcavalrynginx:0.0.1 .

执行完毕后,再执行docker images,就能看到新的镜像文件了,如下图:

对于tomcat的镜像,请直接使用上一篇文章《 实战docker,编写Dockerfile定制tomcat镜像,实现web应用在线部署》中通过Makefile定制的tomcat镜像,这个镜像的好处是:部署完毕后验证负载均衡能力时,可以通过maven插件直接给tomcat容器部署应用包。

ok,现在我们有了nginx和tomcat的镜像,接下来要做的就是run一个nginx容器,再run两个tomcat容器,来实现负载均衡,run这三个容器可以有如下两种方式来实现: 1. 执行三个docker run命令,启动三个容器; 2. 使用docker compose来实现批量启动多个容器;

我们先来试试第一种方式吧: 1. 启动第一个tomcat容器,起名tomcat001,在终端输入:

docker run --name=tomcat001 -p 8081:8080 -e TOMCAT_SERVER_ID=tomcat_server_001 -idt bolingcavalrytomcat:0.0.1
  1. 启动第二个tomcat容器,起名tomcat002,在终端输入:
docker run --name=tomcat002 -p 8082:8080 -e TOMCAT_SERVER_ID=tomcat_server_002 -idt bolingcavalrytomcat:0.0.1
  1. 这时候执行docker ps就能看到已经有两个容器启动了,如下图:

两个tomcat容器各自暴露了自己的8080端口,然后分别映射到了当前电脑的8081和8082两个端口,也就是说我们访问localhost:8081以及localhost:8082就能访问到两个容器上的tomcat了,打开浏览器试试,如下图:

  1. 还记得上一篇文章《 实战docker,编写Dockerfile定制tomcat镜像,实现web应用在线部署》中提到的,通过maven部署war包到tomcat上去的方法么?请按照文章中的步骤,从git上下载代码,然后修改pom.xml中的参数,如下图:

将上图红框中的端口改为8081后,在pom.xml所在目录下执行:

mvn clean package -U -Dmaven.test.skip=true tomcat7:redeploy

然后再将端口改为8082再执行同样的命令,这样就能把war包分别部署到两个tomcat容器上了,这时候用浏览器访问http://localhost:8081/loadbalancedemo/hello就能看到下图效果:

访问http://localhost:8082/loadbalancedemo/hello的效果如下:

  1. 在终端输入以下命令,启动nginx:
docker run --name=ngx001 --link=tomcat001:t01 --link=tomcat002:t02 -p 80:80 -idt bolingcavalrynginx:0.0.1

这里重点看一下参数–link=tomcat001:t01,–link表示当前命令启动的容器ngx001要和另一个名叫tomcat001的容器建立连接,“tomcat001:t01“中的“t01“表示t01是连接建立后tomcat001的别名,或者可以理解为:ngx001启动后,/etc/host文件中加入了一条记录,ip是tomcat001的ip,name是t01。

我们输入docke exec -it ngx001 /bin/bash登录ngx001,再输入cat /etc/hosts即可看到如下图:

也就是说,在ngx001容器内部,所有访问t01的地方,实际上都访问的是tomcat001对应的ip,搞清楚了这一点,再看看之前配置的nginx的nginx.conf文件:

upstream tomcat_client {
         server t01:8080 weight=1;
         server t02:8080 weight=1;
    } 

这里面的t01,t02和link参数中的t01,t02对应,这样nginx在用t01做为域名做请求转发的时候,请求就能到tomcat001和tomcat002上了。

进行到这里,我们已经实现了nginx+tomcat实现负载均衡的效果,但是启动三个容器要执行三次命令似乎挺麻烦,有没有什么批量执行的方法呢?自己写shell,把所有命令都放在里面?呃,这么做也行,但是其他的批量操作呢?比如停止,恢复,构建镜像,查看信息等,所以使用compose是个更好的选择,compose是用于定义和运行复杂Docker应用的工具,可以批量的处理多个容器,这里我们仅做一次小小的尝试,不做深入探讨了。

直接上代码了,新建一个docker-compose.yml文件,内容如下:

version: '2'
services:
  nginx001: 
    image: bolingcavalrynginx:0.0.1
    links: 
      - tomcat001:t01 
      - tomcat002:t02
    ports: 
      - "80:80" 
    restart: always 
  tomcat001: 
    image: bolingcavalrytomcat:0.0.1
    ports: 
      - "8081:8080"
    environment:
      TOMCAT_SERVER_ID: tomcat_server_001
    restart: always
  tomcat002: 
    image: bolingcavalrytomcat:0.0.1
    ports: 
      - "8082:8080"
    environment:
      TOMCAT_SERVER_ID: tomcat_server_002
    restart: always

每个容器都定义成一个节点,节点内有具体的参数键值对,我们之前docker run带上的那些参数都在里面了。

现在可以尝试一下执行docker-compose.yml了,在执行之前请先执行如下的命令,将我们前面启动的三个容器先停止再删除:

docker stop tomcat001 tomcat002 ngx001;docker rm tomcat001 tomcat002 ngx001

然后进入docker-compose.yml文件所在的目录,执行如下命令:

docker-compose up -d

执行完毕后,再执行docker ps查看当前容器信息:

容器已经一次性启动起来了,不过名字似乎变了,被加了前缀,这个前缀的具体内容和当前目录有关,现在浏览器里面输入localhost试试,顺利打开tomcat的欢迎页:

请大家参照之前的方式通过”mvn clean package -U -Dmaven.test.skip=true tomcat7:redeploy”命令将war包分别部署在两个tomcat上,再访问“http://localhost/loadbalancedemo/hello“来验证nginx是否将请求分发到了不同的tomcat上。

以上就是利用link和docker compose部署server负载均衡的实战了,有一点问题大家可能发现了,就是每次部署war包很麻烦,其实除了这种方式,我们还可以制作tomcat的镜像的时候,在Dockerfile中写命令将war包复制到镜像中去,也可以Docker run的时候通过-v参数挂载当前电脑的实际目录到tomcat的webapps目录上,这两种方法实现起来都很简单,大家有兴趣的话可以试试。

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏云计算教程系列

如何在Ubuntu 16.04上使用Vault来保护敏感的Ansible数据

Ansible Vault是一项允许用户加密Ansible项目中的值和数据结构的功能。这提供了保证Ansible成功运行敏感数据所必备的能力。

804
来自专栏云计算教程系列

如何在Ubuntu上创建Sudo用户[快速入门]

该sudo命令提供了一种机制,用于向普通用户授予通常仅对root用户可用的管理员权限。本指南将向您展示在Ubuntu上创建具有sudo访问权限的新用户的最简单方...

600
来自专栏编程坑太多

『高级篇』docker之kubernetes搭建集群添加认证授权(上)(38)

kubernetes的安装有几种方式,不管是kube-admin还是社区贡献的部署方案都离不开这几种方式:

734
来自专栏北京马哥教育

MySQL高可用,数据之船不再翻

前言 上篇文章我们介绍了使用pacemkaer+corosync实现简单的nginx高可用, 这篇文章我们介绍如何使用pacemaker+corosync实现M...

2756
来自专栏IT可乐

Linux系列教程(十八)——Linux文件系统管理之文件系统常用命令

  通过前面两篇博客,我们介绍了Linux系统的权限管理。Linux权限管理之ACL权限 介绍了通过设定 ACL 权限,我们为某个用户指定某个文件的特定权限,这...

17810
来自专栏雨过天晴

原 荐 docker清理

1382
来自专栏雨过天晴

转 Mac OS/Linux命令查询网络端口占用情况

1123
来自专栏技术博文

linux 查看系统信息命令(比较全)

linux 查看系统信息命令是linux初学者必备的基础知识, 这些命令也非常有用, 因为进入linux第一件事就可能是首先查看系统信息, 因此必要的系统的学习...

3277
来自专栏欧科云

斐讯K3路由器 实现frp内网穿透

家里的装的是联通的光纤,安装后一直获取的是公网IP,家里架设了NAS和路由都可以通过外网访问,但是忽然有一天不能访问了,经过检查发现竟然成了内网IP,经过多方交...

3044
来自专栏PHP技术大全

使用PHP搭建Web版Docker管理系统实践

团队中使用容器比较频繁,但并不是所有人都可以登陆服务器去执行命令,但是又需要用到docker,所以有一个需求通过web来管理docker,而其他语言并不怎么熟悉...

1161

扫码关注云+社区