昨天收了一篇好文章 nginx常用功能全揭秘,想着今天来按照步骤配置一下nginx代理的,结果在使用docker的时候一直出问题,才诞生了这篇关于docker配置nginx负载均衡。
首先在宿主机上创建两个两个目录n1,n2,分别作为两台nginx服务器的目录。
mkdir -p n1 n2
然后分别在目录里新建一个index.html文件,并输入内容作为nginx集群配置成功的后页面呈现的标识。
cd n1 && echo ‘this is n1‘ >> index.html
和 cd n2 && echo ‘this is n2‘ >> index.html
3.按照教程预先在集群中部署两台nginx的目标服务器d的容器
docker run --name nginx1 -d -p 8081:80 -v /Users/道长/Desktop/wwwphp/nginx/n1:/usr/share/nginx/html --link nginx:nginx nginx
docker run --name nginx2 -d -p 8081:80 -v /Users/道长/Desktop/wwwphp/nginx/n2:/usr/share/nginx/html --link nginx:nginx nginx
4.然后我们再创建一个nginx的代理服务器
docker run --name nginx -d -p 8080:80 nginx
5.修改我们nginx的配置文件,分别在upstream和server里配置好我们的两个目标服务器,结果你会发现页面直接呈现的是 “502 Bad Gateway”,当处理到这里的时候,我是直接蒙圈了,明明配置的是对的,为啥会出现这种无法访问的情况呢,然后我们用
docker logs nginx
查看nginx代理容器的的日志,你会发现有如下提示:"1 connect() failed (111: Connection refused) while connecting to upstream, client: 172.17.0.1, server: 127.0.0.1, request: "GET / HTTP/1.1", upstream: "http://172.17.0.3:8082/", host: "localhost:8080"
2018/11/24 10:10:10 [warn] 6#6: 1 upstream server temporarily disabled while connecting to upstream, client: 172.17.0.1, server: 127.0.0.1, request: "GET / HTTP/1.1", upstream: "http://172.17.0.3:8082/", host: "localhost:8080"
2018/11/24 10:10:11 [error] 6#6: 1 no live upstreams while connecting to upstream, client: 172.17.0.1, server: 127.0.0.1, request: "GET /favicon.ico HTTP/1.1", upstream: "http://tomcatserver1/favicon.ico", host: "localhost:8080", referrer: "http://localhost:8080/"
172.17.0.1 - - [24/Nov/2018:10:10:11 +0000] "GET /favicon.ico HTTP/1.1" 502 559 "http://localhost:8080/" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.102 Safari/537.36" "-"
2018/11/24 10:10:11 [error] 6#6: 1 no live upstreams while connecting to upstream, client: 172.17.0.1, server: 127.0.0.1, request: "GET / HTTP/1.1", upstream: "http://tomcatserver1/", host: "localhost:8080"我们初步怀疑是网络不通的原因,用
docker exec -it nginx /bin/bash
进入到nginx代理容器里,去试着ping一下nginx是否通畅,这个时候你就会发现神奇的一幕,我们的nginx容器里居然没有 ping 的命令,在用yum来安装一下吧,纳尼?yum命令也没有。是不是有些崩溃,有些想卸载docker了,请施主稍安勿躁,既然nginx的容器这么干净,那么我们就创建一个centos的容器来用centos容器ping来ping nginx 的容器,结果你回发现如我们猜想的一样,果然是容器间通信造成的。此时我们的解决办法如下(原理方法请参考 Docker容器学习梳理--容器间网络通信设置):
1.搭建一个网桥
docker network create bri1
2.删除原docker容器,然后重新创建新的nginx容器,命令如下
docker run --name nginx-test1 -d -p 8081:80 --network bri1 -v /Users/amber/Desktop/wwwphp/nginx/n1:/usr/share/nginx/html --link nginx:nginx nginx
docker run --name nginx-test2 -d -p 8082:80 --network bri1 -v /Users/amber/Desktop/wwwphp/nginx/n2:/usr/share/nginx/html --link nginx:nginx nginx
docker run --name nginx -d -p 8080:80 --network bri1 -v /Users/amber/Desktop/wwwphp/nginx:/etc/nginx/conf.d nginx
docker run --name nginx -d -p 8080:80 --network bri1 nginx
docker run --name centos -itd --network bri1 centos
3.创建完成之后,我们
docker inspect nginx|grep IPAdress
来查看我们的nginx代理的ip地址,然后docker exec -it centos /bin/bash
进入到centos容器里用ping命令来来ping我们nginx代理的ip地址 我本机nginx容器的ip为172.12.0.2 所以我们ping 172.12.0.2
此时我们发现可以ping通,此刻我们已经距离成功不远了。然后我们再修改nginx的配置文件
upstream tomcatserver1 {
ip_hash
server 172.20.0.2:8081;
server 172.20.0.3:8082;
}
server {
listen 80;
server_name 127.0.0.1;
#charset koi8-r;
#access_log logs/host.access.log main;
location / {
proxy_pass http://tomcatserver1;
index index.html index.htm;
}
}
此刻我们重启nginx代理,会发现依旧不成功,为什么呢?配置是ok的,然后容器间也可以相互通信了,难道是端口??? 此刻我们进入到centos容器里然后用
curl 172.12.0.2:8081
和curl 172.12.0.2
来获取我们目标服务器的内容,我们会发现没有加端口号的居然成功了,原来我们再创建容器的时候设置了 "-p 8081:80"里面的8081只是我们的docker在监听我们本机的端口,你在宿主机上用lsof -i:8081
就会发现监听的进程,而我们容器间的通信走的是bri1的网桥,并没有经过我们的宿主机端口,所以我们只需要把代理服务器的upstream里的主机修改成upstream nginx_proxy{ ip_hash server 172.12.0.2; server 172.12.0.3; }
最后再重启我们的代理服务器,大功告成,每刷新一次,就会切切换集群中的nginx服务器。期间发现了另一篇好文负载均衡器技术Nginx和F5的优缺点对比,有兴趣的朋友可以看一看,欢迎感兴趣的朋友一起切磋交流 QQ:591382275(密码:王道长),在此感谢我师傅和亮哥的指导。
原文地址:http://blog.51cto.com/12165603/2321582