在docker上实现nginx的反向代理tomcat

avatar 2019年10月22日16:11:16 评论 1,474 次浏览

前面已经介绍了Docker的基本用法和Docker的安装,以及项目的打包等等。如果把项目使用的实际工作中这里做一个实验,我们实验的是一个nginx和一个tomcat,需要生成两个镜像,并使用nginx反向代理到tomcat,通过访问nginx的80或者443端口把请求转发给tomcat上处理后返回客户端。这里有几个问题需要提前说明一下,这是我们这次试验的重点:1、容器不能自动关闭或退出 2、容器需要访问宿主机或者外网 3、宿主机文件copy到容器中 4、容器日志映射到本地 下面围绕上面的四个点进行试验,试验环境就一台centos7的服务器。

1、创建一个容器并后台运行

安装方法参考docker的安装方法,如何使用也可以参考docker的基本使用。不会也没关系,只要安装成功即可,先看一下是否有镜像在创建容器:

[root@wulaoer ~]# docker ps -a
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS               NAMES
[root@wulaoer ~]# docker images
REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE

下载镜像,如果有自己的私有仓库可以下载自己的私有镜像直接在pull后面加自己的私有仓库地址即可:

[root@wulaoer ~]# docker pull nginx
Using default tag: latest
latest: Pulling from library/nginx
b8f262c62ec6: Pull complete 
e9218e8f93b1: Pull complete 
7acba7289aa3: Pull complete 
Digest: sha256:aeded0f2a861747f43a01cf1018cf9efe2bdd02afd57d2b11fcc7fcadc16ccd1
Status: Downloaded newer image for nginx:latest
[root@wulaoer ~]# docker pull tomcat
Using default tag: latest
latest: Pulling from library/tomcat
092586df9206: Pull complete 
ef599477fae0: Pull complete 
4530c6472b5d: Pull complete 
d34d61487075: Pull complete 
272f46008219: Pull complete 
12ff6ccfe7a6: Pull complete 
f26b99e1adb1: Pull complete 
21bec9c8ea28: Pull complete 
13c2683e0a3b: Pull complete 
9d4ac4f1904a: Pull complete 
Digest: sha256:57322bca4f6068ade10edef67c61ae5713790665c1e9e4628041726fc23fa71c
Status: Downloaded newer image for tomcat:latest
[root@wulaoer ~]# docker images
REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
tomcat              latest              87ae08c1e3fb        2 days ago          511MB
nginx               latest              f949e7d76d63        2 weeks ago         126MB

下载有点慢,因为是国外的网站稍安勿躁。下面创建两个容器,一个nginx,一个tomcat。

[root@wulaoer ~]# docker run --name nginx-dev -it -p 80:80 -d nginx
beafe325c0b84c11904ef8eb31e4e6bafdcdaa058843c824c8caf6d05cc1211e
[root@wulaoer ~]# docker run --name tomcat-dev -it -p 8080:8080 -d tomcat
b5d9141c364047410ed3d97d02f6a6648480f5f3bc676aeb3b0cc3aeca643838
[root@wulaoer ~]# docker ps -a
CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS              PORTS                    NAMES
b5d9141c3640        tomcat              "catalina.sh run"        8 seconds ago       Up 8 seconds        0.0.0.0:8080->8080/tcp   tomcat-dev
beafe325c0b8        nginx               "nginx -g 'daemon of…"   39 seconds ago      Up 38 seconds       0.0.0.0:80->80/tcp

使用宿主机的80端口映射到容器的80端口,8080端口映射到tomcat的8080端口,这里创建的时候使用了一个参数-d,后台运行容器。我们配置一下,看一下我们访问的时候是否能够访问到我们配置的内容。

[root@wulaoer ~]# docker exec -it nginx-dev /bin/bash
root@beafe325c0b8:/# cd /etc/nginx/conf.d/
root@beafe325c0b8:/etc/nginx/conf.d# ls
default.conf

我们可以查看一下default.conf文件,查看一下访问目录路径,然后在访问目录下修改index.html文件

root@beafe325c0b8:/etc/nginx/conf.d# cd /usr/share/nginx/html/
root@beafe325c0b8:/usr/share/nginx/html# ls
50x.html  index.html
root@beafe325c0b8:/usr/share/nginx/html# echo "this is nginx" > index.html 
root@beafe325c0b8:/usr/share/nginx/html# exit
exit
[root@wulaoer ~]# curl http://10.211.55.41
this is nginx

修改成功,访问正常,下面修改tomcat的配置文件。

[root@wulaoer ~]# docker exec -it tomcat-dev /bin/bash
root@b5d9141c3640:/usr/local/tomcat# cd webapps/ROOT/
root@b5d9141c3640:/usr/local/tomcat/webapps/ROOT# ls
RELEASE-NOTES.txt  bg-button.png  bg-upper.png  tomcat-power.gif  tomcat.png
WEB-INF            bg-middle.png  favicon.ico   tomcat.css        tomcat.svg
asf-logo-wide.svg  bg-nav.png     index.jsp     tomcat.gif
root@b5d9141c3640:/usr/local/tomcat/webapps/ROOT# echo "This is tomcat" > index.jsp
root@b5d9141c3640:/usr/local/tomcat/webapps/ROOT# exit
exit
[root@wulaoer ~]# curl http://10.211.55.41:8080
This is tomcat

容器已经创建完成,应用正常不会自动退出或者重启。下面学一下反向代理,所以需要nginx反向指定到tomcat的url。

2、容器需要访问宿主机或者外网

我们先使用容器内网访问,需要先查看一下tomcat-dev的IP地址,可以参考以下三种方式:

2.1 第一种查看方式

[root@wulaoer ~]# docker inspect tomcat-dev   #容器的所有状态信息

2.2 第二种查看方式

[root@wulaoer ~]# docker inspect --format='{{.NetworkSettings.IPAddress}}' tomcat-dev
172.17.0.3

2.3 第三种查看方式

[root@wulaoer ~]# docker exec -it tomcat-dev ip addr
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever
66: eth0@if67: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default 
    link/ether 02:42:ac:11:00:03 brd ff:ff:ff:ff:ff:ff link-netnsid 0
    inet 172.17.0.3/16 brd 172.17.255.255 scope global eth0
       valid_lft forever preferred_lft forever

使用容器的IP地址进行反向代理,容器中默认没有安装vim,所以需要自己手动安装一下:

[root@wulaoer ~]# docker exec -it nginx-dev /bin/bash
root@beafe325c0b8:/# cd /etc/nginx/conf.d/
root@beafe325c0b8:/etc/nginx/conf.d# vi default.conf 
bash: vi: command not found
root@beafe325c0b8:/etc/nginx/conf.d# apt-get update          #需要先update才可以安装
root@beafe325c0b8:/etc/nginx/conf.d# apt-get install vim     #安装vim
root@beafe325c0b8:/etc/nginx/conf.d# vim default.conf 
.........
    location / {
        #root   /usr/share/nginx/html;
        #index  index.html index.htm;
        proxy_pass http://172.17.0.3:8080;         #也可以替换成宿主机的,如果是集群可以替换成集群的slb
    }
...........
root@beafe325c0b8:/etc/nginx/conf.d# /etc/init.d/nginx reload
[ ok ] Reloading nginx: nginx.
root@beafe325c0b8:/etc/nginx/conf.d# exit
exit
[root@wulaoer ~]# curl http://10.211.55.41
This is tomcat

我们这是一个nginx对应一个tomcat,如果有多个tomcat,这就需要使用到slb负载均衡,这时需要使用nginx反向代理宿主机的IP地址或者外网的slb地址以及端口。这时容器的网络模式就需要改变了,下面重新创建一个容器:

[root@wulaoer ~]# docker run --name nginx-host -it --net=host -d nginx /bin/bash
95650126763e4281c7d4cc98fb752dcbda76491d8091fa1f1dece167ced4351e
[root@wulaoer ~]# docker run --name tomcat-host --net=host  -d tomcat 
4ec00d68b58247c8ecd0c6d401d4ec53757533fbe3514ab5ec1ca0c1ad8ec21c

因为docker的host模式是和宿主机公用一个Network Namespace,所以docker容器是没有IP的,使用的端口也不存在映射,下面配置一下host模式的nginx+tomcat,在设置nginx反向代理时我们把使用的docker容器的IP换成宿主机的IP即可

3、宿主机文件copy到容器中

下面举个例子docker容器的时间和宿主机的时间不一致,那么需要把容器时间和宿主机的时间一致如何操作呢?目前机器少还行执行一下时间更新,如果容器过多,就不允许这样操作了,首先我们要解决的事服务时间同步,然后容器同步宿主机即可,下面看一下时间同步方法:

[root@wulaoer ~]# date
Fri Oct 18 16:51:15 CST 2019
[root@k8s-node3 ~]# docker exec -it nginx-dev /bin/bash
root@072973cdf516:/# date
Fri Oct 18 08:51:19 UTC 2019
root@072973cdf516:/#

宿主机和容器时间不同步,我们需要把宿主机的时间文件copy到容器中看一下。

[root@wulaoer ~]# docker cp -L /usr/share/zoneinfo/Asia/Shanghai nginx-dev:/etc/localtime 
[root@wulaoer ~]# date
Fri Oct 18 16:57:49 CST 2019
[root@wulaoer ~]# docker exec -it nginx-dev /bin/bash
root@072973cdf516:/# date
Fri Oct 18 16:57:53 CST 2019
root@072973cdf516:/#

这里需要注意copy到容器中,容器中不能存在这个文件,不回覆盖,如果容器中存在文件,就会报错:

Error response from daemon: Could not find the file /usr/share/usr/share/zoneinfo/Asia in container nginx-dev

4、容器日志映射到本地

把容器的日志映射到本地,需要使用到参数-v,多个映射多个-v。下面做一个nginx测试,把nginx的日志映射到本地,我们情况一下日志内容看是否和docker容器中是否同步:

[root@wulaoer ~]# mkdir -p /opt/logs/nginx
[root@wulaoer ~]# docker run --name=nginx-logs -v /opt/logs/nginx:/var/log/nginx -p 80:80 -d nginx
cf1342b89393ac54d48f0c565dda7f6e7dc6d829f2c3ef2fe06e4c9fd1dd708d
[root@wulaoer ~]# ls /opt/logs/nginx/
access.log  error.log

已经创建好容器,并且日志已经挂在本地,下面测试一下日志的同步性,先把时间同步,并清理本地的日志文件内容:

[root@wulaoer ~]# docker cp -L /usr/share/zoneinfo/Asia/Shanghai nginx-logs:/etc/localtime 
[root@wulaoer ~]# cd /opt/logs/nginx/
[root@wulaoer nginx]# ll
total 4
-rw-r--r--. 1 root root 93 Oct 18 17:07 access.log
-rw-r--r--. 1 root root  0 Oct 18 17:06 error.log
[root@wulaoer nginx]# echo "" > access.log 
[root@wulaoer nginx]# ll
total 4
-rw-r--r--. 1 root root 1 Oct 18 17:13 access.log
-rw-r--r--. 1 root root 0 Oct 18 17:06 error.log
[root@wulaoer nginx]#

看一下容器中的内容是否还存在:

[root@wulaoer nginx]# docker exec -it nginx-logs /bin/bash
root@cf1342b89393:/# cd /var/log/nginx/
root@cf1342b89393:/var/log/nginx# ls -l
total 4
-rw-r--r--. 1 root root 1 Oct 18 17:13 access.log
-rw-r--r--. 1 root root 0 Oct 18 17:06 error.log

说明日志数据已经同步到宿主机上,下面我们循环执行看一下日志的产生:

[root@wulaoer nginx]# for ((i=1;i<=100;i++));do curl http://10.211.55.41; done

容器日志都保存在宿主机上,可以设置自动分割,分类可以在宿主机上操作,不过建议每天做定时任务不需要很久才执行一次,可以先归类后压缩。

avatar

发表评论

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen: