无法使用Docker,Consul和nginx进行负载平衡 [英] Unable to load balance using Docker, Consul and nginx
问题描述
版本:'2'
服务:
口音:
构建:
上下文:./accent
图像:口音
容器名称:口音
重新启动:总是
端口:
- 80
consul:
图像:gliderlabs / consul-server:最新
容器名:consul
主机名:$ {MYHOST}
重新启动:总是
端口:
- 8300: 8300
- 8400:8400
- 8500:8500
- 8600:53 / udp
命令:-advertise $ {MYHOST} -data-dir / tmp / consul -bootstrap - 客户端0.0.0.0
注册人:
图片:gliderlabs / registrator:最新
容器名:注册人
主机名:$ {MYHOST}
network_mode:主机
重新启动:总是
卷:
- /var/run/docker.sock:/tmp/docker.sock
命令:-ip $ {MYHOST} consul:// $ {MYHOST}:8500
nginx:
container_name:nginx
image:nginx:latest
resta rt:总是
卷:
- / etc / nginx
ports:
- 8181:80
consul-template:
container_name:consul-template
build:
上下文:./consul-template
network_mode:host
restart:always
volumes_from:
- nginx
volumes:
- /var/run/docker.sock:/tmp/docker.sock
命令:-consul = $ {MYHOST}:8500 -wait = 5s -template =/ etc / ctmpl / nginx.ctmpl: /etc/nginx/nginx.conf:docker kill -s HUP nginx
第一个服务 - 口音 - 是我的Web服务,我需要负载平衡。当我运行这个命令:
$ docker-compose up
我看到所有服务开始运行,我看不到任何错误消息。看起来好像一切都是完美的。当我运行
$ docker ps
我在控制台中看到这个:
... NAMES STATUS PORTS
consul-template Up 45秒
consul Up 56秒0.0.0.0:8300->8300/tcp,0.0.0.0:8400->8400/tcp,8301-8302 / tcp,8301-8302 / udp, 0.0.0.0:8500->8500/tcp,8600 / tcp,8600 / udp,0.0.0.0:8600->53/udp
nginx上升41秒0.0.0.0:8181->80/tcp
注册商Up 56秒
重点加56秒0.0.0.0:32792->80/tcp
请注意最后一行,特别是PORTS列。您可以看到,此服务发布32792端口。要检查我的Web服务是否可以实现,请转到我的主机(运行docker组合的机器)上的 127.0.0.1:32972
,然后在浏览器中看到: / p>
Hello World
这正是我想看到的。但是,这不是我终于想要的。请看看docker ps命令的输出,你会看到,我的nginx服务发布了8181端口。所以,我的期望是当我去这个地址 - 127.0.0.1:8181
- 我会看到完全相同的Hello world页面。但是,不是。在浏览器中,我看到坏网关错误消息,在nginx日志中我看到这个错误信息
nginx | 2017/01/18 06:16:45 [error] 5#5:* 5 connect()failed(111:Connection refused)while connection to upstream,client:172.18.0.1,server:,request:GET / favicon。 ico HTTP / 1.1,上游: http://127.0.0.1:32792/index.php,host:127.0.0.1:8181
真的很有趣,因为nginx会做我期望的 - 上游 http://127.0.0.1:32792/index.php 。但我不知道为什么会失败。顺便说一句,这是nginx.conf(使用领事馆模板自动创建)如下所示:
worker_processes 1;
events {
worker_connections 1024;
}
http {
sendfile on;
上游app_servers {
服务器127.0.0.1:32792;
}
server {
listen 80;
root / code;
index index.php index.html;
location / {
try_files $ uri / $ uri / /index.php;
}
位置〜\.php $ {
proxy_pass http:// app_servers;
proxy_redirect关闭;
proxy_set_header Host $ host;
proxy_set_header X-Real-IP $ remote_addr;
proxy_set_header X-Forwarded-For $ proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Host $ server_name;
}
位置〜/\.ht {
拒绝所有;
}
}
}
我会不会改变任何东西,因为这个nginx.conf对我来说看起来不错。试图理解为什么它不起作用,我炮击到nginx容器,并提出了几个命令:
$ curl accent
Hello World
$ curl 127.0.0.1:32972
curl:(7)无法连接到127.0.0.1端口32972:拒绝连接
$ curl口音:32972
curl:(7)无法连接到口音32972:连接拒绝
再次,这很有趣,因为nginx容器在端口 80
下看到我的Web服务,而不是在其已发布的 32972
端口。无论如何,在这个阶段我不知道为什么它不起作用,如何解决它。我只是猜测,它是以某种方式连接的方式,如何在docker-compose.yml中配置网络。我在口音和nginx服务上尝试了 network_mode:host
的各种组合,但无效 - 口音停止工作或nginx或两者兼有。所以,我需要一些帮助。
当您进行端口绑定时,它会从容器发布一些端口(在
)。与您的口音容器相同的网络中的容器可以访问您的容器端口口音
例如)和您的主机上的某些端口(随机 32792
在主机上 80
由口音
(与口音:80
)由于docker-compose服务名称解析。您可以使用口音:32792
从您的主机访问口音:80
。当您从 nginx
容器中请求 127.0.0.1:32792
时,您只能访问 nginx
容器 32792
端口,而不是口音
。 口音:32792
是不正确的URL( 80
端口打开口音
, 32792
在主机上)。但是当您将 nginx
容器添加到主机$时,
127.0.0.1:32792
c $ c>网络。但是我注意到您在 curl
调用中使用不正确的端口。您的口音:80
发布到主持人 32792
,但您要求 32972
。
What I want to achive is load balancing using this stack: Docker, Docker Compose, Registrator, Consul, Consul Template, NGINX and, finally, a tiny service that prints out "Hello world" in browser. So, at this moment I have a docker-compose.yml file. It looks like so:
version: '2'
services:
accent:
build:
context: ./accent
image: accent
container_name: accent
restart: always
ports:
- 80
consul:
image: gliderlabs/consul-server:latest
container_name: consul
hostname: ${MYHOST}
restart: always
ports:
- 8300:8300
- 8400:8400
- 8500:8500
- 8600:53/udp
command: -advertise ${MYHOST} -data-dir /tmp/consul -bootstrap -client 0.0.0.0
registrator:
image: gliderlabs/registrator:latest
container_name: registrator
hostname: ${MYHOST}
network_mode: host
restart: always
volumes:
- /var/run/docker.sock:/tmp/docker.sock
command: -ip ${MYHOST} consul://${MYHOST}:8500
nginx:
container_name: nginx
image: nginx:latest
restart: always
volumes:
- /etc/nginx
ports:
- 8181:80
consul-template:
container_name: consul-template
build:
context: ./consul-template
network_mode: host
restart: always
volumes_from:
- nginx
volumes:
- /var/run/docker.sock:/tmp/docker.sock
command: -consul=${MYHOST}:8500 -wait=5s -template="/etc/ctmpl/nginx.ctmpl:/etc/nginx/nginx.conf:docker kill -s HUP nginx"
The first service - accent - is that my web service that I need to load balance. When I run this command:
$ docker-compose up
I see that all services start to run and I see no error messages. It looks as if everything is just perfect. When I run
$ docker ps
I see this in the console:
... NAMES STATUS PORTS
consul-template Up 45 seconds
consul Up 56 seconds 0.0.0.0:8300->8300/tcp, 0.0.0.0:8400->8400/tcp, 8301-8302/tcp, 8301-8302/udp, 0.0.0.0:8500->8500/tcp, 8600/tcp, 8600/udp, 0.0.0.0:8600->53/udp
nginx Up 41 seconds 0.0.0.0:8181->80/tcp
registrator Up 56 seconds
accent Up 56 seconds 0.0.0.0:32792->80/tcp
Please, pay attention to the last row and especially to PORTS column. As you can see, this service publishes 32792 port. To check that my web service is achievable I go to 127.0.0.1:32972
on my host machine (the machine where I run docker compose up) and see this in browser:
Hello World
This is exactly what I wanted to see. However, it is not what I finally want. Please, have a look at the output of docker ps command and you will see, that my nginx service published 8181 port. So, my expectation is that when I go to this address - 127.0.0.1:8181
- I will see exactly the same "Hello world" page. However, it is not. In browser I see Bad Gateway error message and in nginx logs I see this error message
nginx | 2017/01/18 06:16:45 [error] 5#5: *5 connect() failed (111: Connection refused) while connecting to upstream, client: 172.18.0.1, server: , request: "GET /favicon.ico HTTP/1.1", upstream: "http://127.0.0.1:32792/index.php", host: "127.0.0.1:8181"
It is really interesting, because nginx does what I expect it to do - upstreams to "http://127.0.0.1:32792/index.php". But I'm not sure why does it fail. By the way, this is how nginx.conf (created automatically with Consul Template) looks like:
worker_processes 1;
events {
worker_connections 1024;
}
http {
sendfile on;
upstream app_servers {
server 127.0.0.1:32792;
}
server {
listen 80;
root /code;
index index.php index.html;
location / {
try_files $uri/ $uri/ /index.php;
}
location ~ \.php$ {
proxy_pass http://app_servers;
proxy_redirect off;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Host $server_name;
}
location ~ /\.ht {
deny all;
}
}
}
I wouldn't change anything, since this nginx.conf looks good to me. Trying to understand why it does not work, I shelled to nginx container and made a couple of commands:
$ curl accent
Hello World
$ curl 127.0.0.1:32972
curl: (7) Failed to connect to 127.0.0.1 port 32972: Connection refused
$ curl accent:32972
curl: (7) Failed to connect to accent port 32972: Connection refused
Again, it is interesting, because nginx container sees my web service under port 80
and not under its published 32972
port. Anyway, at this stage I do not know why it does not work and how to fix it. I just have a guess, that it is somehow connected to the way, how network is configured in docker-compose.yml. I tried various combinations of network_mode: host
on accent and nginx service, but to no avail - either accent stops working or nginx or both. So, I need some help.
When you do port binding it publish some port from container (80
in accent
e.g.) and some port on your host (random 32792
on host e.g.).Containers in same network as your accent container can access your container port 80
by accent
(same as accent:80
) due to docker-compose services name resolving. You can access accent:80
from your host with accent:32792
. When you are requesting 127.0.0.1:32792
from your nginx
container you can access only nginx
container 32792
port, not accent
. accent:32792
is not correct url from anyway (80
port open on accent
, 32792
on host). But 127.0.0.1:32792
should work when you add nginx
container to host
network. But I noticed that you use incorrect port in curl
call. Your accent:80
published to host 32792
but you request 32972
.
这篇关于无法使用Docker,Consul和nginx进行负载平衡的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!