Docker群集模式负载平衡不像描述的那样工作

更新

我相信罪魁祸首是谁似乎没有监听端口7946.netstat显示7946正在监听节点,但不是主。 当我检查节点的系统日志时,我看到以下错误

 level=error msg="Failed to join memberlist [10.0.0.12] on retry: 1 error(s) occurred:\n\n* Failed to join 10.0.0.12: dial tcp 10.0.0.12:7946: getsockopt: connection refused" 

原始post

我正在AWS中运行三节点群集模式群集; 一个主人和两个工人。 这是群模式不要与1.12之前的docker群混淆。

我用docker-machine创build了所有的服务。 每台机器都运行Ubuntu 15.10和Docker 1.12.3。

 Linux swarm-master-01 4.2.0-42-generic #49-Ubuntu SMP Tue Jun 28 21:26:26 UTC 2016 x86_64 x86_64 x86_64 GNU/Linux 

使用主节点我已经创build了以下的服务

 docker service create --replicas 1 --name myapp -p 3000 myapp 

当我运行docker service ps myapp我得到以下输出

 ID NAME IMAGE NODE DESIRED STATE CURRENT STATE ERROR 02awst8p9pezgpkfzqgz8z79t myapp.1 myapp:latest swarm-node-01 Running Running 19 minutes ago 

正在运行的任务被部署到swarm-node-01。

我检查了公开发布的自动select的端口

 $ docker service inspect myapp | jq .[].Endpoint.Ports[].PublishedPort 30000 

根据文件 :

外部组件(如云负载平衡器)可以访问群集中任何节点的已发布端口上的服务,而不pipe该节点当前是否正在运行该服务的任务 。 群路由中的所有节点都将入口连接到正在运行的任务实例。

但是,当我试图curl没有运行任务的节点时,我正在connection refused

 $ curl $(docker-machine ip swarm-node-01):30000/stats {"uptime":"2016-11-09T14:48:35Z","requestCount":7,"statuses":{"200":7},"pid":1,"open_db_conns":0} $ curl $(docker-machine ip swarm-node-02):30000/stats curl: (7) Failed to connect to [the IP] port 30000: Connection refused 

注意:我擦掉了node-02的IP


我的疑难解答

  • 节点都正确连接到群体
  • 将服务扩展到5(这固有地将任务部署到每个节点)使curl在每个节点上工作,因为任务被部署到每个节点。

更新1

我初始化了群

 docker swarm init --advertise-addr 10.0.0.12:2377 --listen-addr 10.0.0.12:2377 

我检查了从节点syslogs,我看到以下错误

 level=error msg="Failed to join memberlist [10.0.0.12] on retry: 1 error(s) occurred:\n\n* Failed to join 10.0.0.12: dial tcp 10.0.0.12:7946: getsockopt: connection refused" 

我检查了入口端口是否在监听,看起来不是这样

 ubuntu@swarm-master-01:~$ sudo lsof -i :7946 ubuntu@swarm-master-01:~$ cat < /dev/tcp/10.0.0.12/7946 -bash: connect: Connection refused -bash: /dev/tcp/10.0.0.12/7946: Connection refused ubuntu@swarm-master-01:~$ cat < /dev/tcp/0.0.0.0/7946 -bash: connect: Connection refused -bash: /dev/tcp/0.0.0.0/7946: Connection refused 

我现在能够解决这个问题,但是我不知道最初是什么原因造成的。 覆盖networking(端口7946)没有在swarm-master-01上进行监听。 我用netstat -nlt解决了这个问题。 我search了系统日志,发现这些与syslog中的端口有关的错误。

 Nov 8 20:28:20 ubuntu docker[23092]: time="2016-11-08T20:28:20.171385360Z" level=warning msg="2016/11/08 20:28:20 [ERR] memberlist: Failed TCP fallback ping: read tcp 10.0.0.85:54016->10.0.0.13:7946: i/o timeout" Nov 9 18:26:17 swarm-node-01 docker[714]: time="2016-11-09T18:26:17.573441271Z" level=warning msg="2016/11/09 18:26:17 [ERR] memberlist: Failed to send indirect ping: write udp [::]:7946->10.0.0.38:7946: use of closed network connection" 

由于某种原因docker工人拒绝打开这个港口,再听一遍。 以下是我所做的(虽然不合要求)来规避这个问题:

  1. 使用名为swarm-master-02的docker-machine创build另一个节点
  2. 作为主人joinswarm-master-02到集群
  3. 将master-02设置为首领的降级master-01
  4. 在每个节点上重新启动docker守护进程(可能没有必要)

现在除了swarm-master-01以外,所有的机器都按照预期工作。 一个任务在swarm-node-01上运行,curl通过将stream量转发到适当的节点上的适当容器来针对所有节点。 但是,swarm-master-01拒绝在overlaynetworking上收听,curl对这个节点不起作用。 我只能通过从群集中彻底删除swarm-master-01来修复swarm-master-01,重新启动docker守护进程,然后再作为主节点重新join。 现在7946正在那台机器上收听。