无法使用Docker,Consul和nginx进行负载平衡

我想要的是使用这个堆栈进行负载平衡:Docker,Docker Compose,注册器,Consul,Consul Template,NGINX,最后是一个在浏览器中打印出“Hello world”的servlets。 所以,在这个时候我有一个docker-compose.yml文件。 它看起来像这样:

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" 

第一个服务 – 口音 – 是我的Web服务,我需要负载平衡。 当我运行这个命令时:

 $ docker-compose up 

我看到所有的服务开始运行,我看不到错误消息。 它看起来好像一切都是完美的。 当我跑步

 $ docker ps 

我在控制台中看到这个:

 ... 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 

请注意最后一行,特别是PORTS栏。 正如你所看到的,这个服务发布32792端口。 为了检查我的Web服务是否可以实现,我在我的主机(运行docker的机器上)上find127.0.0.1:32972 ,并在浏览器中看到:

 Hello World 

这正是我想看到的。 但是,这不是我最终想要的。 请看看docker ps命令的输出,你会看到,我的nginx服务发布了8181端口。 所以,我的期望是,当我去到这个地址 – 127.0.0.1:8181 – 我会看到完全一样的“Hello world”页面。 但是,事实并非如此。 在浏览器中,我看到错误的网关错误消息,并在nginx日志中看到这个错误消息

nginx | 2017/01/18 06:16:45 [错误] 5#5:* 5连接()失败(111:连接拒绝),当连接到上游时,客户端:172.18.0.1,服务器:,请求:“GET / favicon。 ico HTTP / 1.1“,上游:” http://127.0.0.1:32792/index.php “,主机:”127.0.0.1:8181“

这真的很有趣,因为nginx做了我所期望的 – 上游到“ http://127.0.0.1:32792/index.php ”。 但我不确定它为什么会失败。 顺便说一句,这是如何nginx.conf(与Consul模板自动创build)如下所示:

 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; } } } 

我不会改变任何东西,因为这个nginx.conf看起来不错。 试图了解为什么它不起作用,我炮击nginx容器,并做了几个命令:

 $ 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 

同样有趣的是,因为nginx容器在端口80下看到我的web服务,而不在其发布的32972端口下。 无论如何,在这个阶段,我不知道为什么它不工作,以及如何解决这个问题。 我只是猜测,它是以某种方式连接到docker-compose.yml中configurationnetworking的方式。 我尝试了network_mode: host在口音和nginx服务上的各种组合,但无济于事 – 重音停止工作或nginx或两者兼而有之。 所以,我需要一些帮助。

当你做端口绑定时,它发布一个端口从容器( accent 80例如)和您的主机上的一些端口(例如主机上的随机32792 )。与重音容器在同一networking中的容器可以通过accent访问您的容器端口80 accent:80 )由于docker-compose服务名称parsing。 您可以从您的主机访问accent:80accent:32792 。 当你从你的nginx容器请求127.0.0.1:32792 ,你只能访问nginx容器的32792端口,而不是accentaccent:32792反正是不正确的url(在accent上打开80端口,在主机上打开32792 )。 但是当您将nginx容器添加到hostnetworking时, 127.0.0.1:32792应该可以工作。 但是我注意到你在curl调用中使用了不正确的端口。 您的accent:80发布到主机32792但你请求32972

Interesting Posts