如何将Docker Swarm连接到多个Consul服务器以实现故障转移?

我正在与领事经营docker群。 我有一个由三个节点相连的用于故障转移的consul集群。 问题是我只能连接我的团队工作人员和主人到一个节点,如果该节点停止,群体停止工作。 那么我怎样才能将群工和主人连接到我的所有节点呢? 如果从主服务器运行以下命令,则会将我的群集环境连接到单个consul服务器:

#### REFERENCE # {{master_i}} is the IP address of the master server # {{consul_i}} is the IP address of the consul server # {{worker_i}} is the IP address of a worker server #### START THE MASTER docker run --restart=unless-stopped --name=swarm-manager0 -d -p 4000:4000 swarm manage -H :4000 --replication \ --advertise {{master_0}}:4000 \ consul://{{consul_0}}:8500 #### START THE WORKERS REMOTELY FROM THE MASTER docker -H={{worker_0}}:2375 run -d --restart=unless-stopped --name=swarm-worker0 swarm join \ --advertise={{worker_0}}:2375 \ consul://{{consul_0}}:8500/ docker -H={{worker_1}}:2375 run -d --restart=unless-stopped --name=swarm-worker1 swarm join \ --advertise={{worker_1}}:2375 \ consul://{{consul_0}}:8500/ docker -H={{worker_2}}:2375 run -d --restart=unless-stopped --name=swarm-worker2 swarm join \ --advertise={{worker_2}}:2375 \ consul://{{consul_0}}:8500/ #### START THE WORKER SERVICE DISCOVERY docker -H={{worker_0}}:2375 run -d --restart=unless-stopped \ -h {{worker_0}} --name registrator0 -v /var/run/docker.sock:/tmp/docker.sock gliderlabs/registrator \ consul://{{consul_0}}:8500 docker -H={{worker_1}}:2375 run -d --restart=unless-stopped \ -h {{worker_1}} --name registrator1 -v /var/run/docker.sock:/tmp/docker.sock gliderlabs/registrator \ consul://{{consul_0}}:8500 docker -H={{worker_2}}:2375 run -d --restart=unless-stopped \ -h {{worker_2}} --name registrator2 -v /var/run/docker.sock:/tmp/docker.sock gliderlabs/registrator \ consul://{{consul_0}}:8500 

请注意,只需在每个docker run命令的末尾添加两个额外的consul://{{consul_i}}:8500 (对于其他两个consul服务器),将不会将容器连接到其他consul服务器。

根据@slugonamission,没有办法将swarm连接到多个consul服务器的多个IP地址。

但是,我能够创build一个坐在我的领事服务器前的haproxy负载均衡器。 因此,我的负载均衡器将所有我的负责服务器上的负载均衡器端口8500的所有stream量转发到端口8500。 通过这样做,我可以使用我的负载均衡器的IP地址来代替{{CONSUL0}} 。 下面是我非常基本的haproxy.cfg

 # $CONSUL0 $CONSUL0 and $CONSUL0 are the IP addresses of my consul servers global log 127.0.0.1 local0 notice maxconn 2000 user haproxy group haproxy defaults log global mode http option httplog option dontlognull retries 3 option redispatch timeout connect 5000 timeout client 10000 timeout server 10000 listen appname 0.0.0.0:8500 mode http stats enable stats uri /haproxy?stats stats realm Strictly\ Private stats auth ubuntu balance roundrobin option httpclose option forwardfor server consul0 $CONSUL0:8500 check server consul1 $CONSUL1:8500 check server consul2 $CONSUL2:8500 check 

改变后,我的领事服务器可以单独下去,群体将继续工作。

实际上似乎没有办法直接从盒子里面做出来。 最终,Swarm(通过libkv)取消Consul HTTP API ,它只连接到单个指定的端点。 更糟的是,如果多个Consul主机通过, libkv会抛出exception。

有一种方法可以通过一些更多的工作来达到这个目的。 如果您在运行Swarm的每个节点上启动一个Consul代理,并将其join其中一个Consul服务器,他们将了解群集的状态。 如果您然后指定Consul代理的地址作为Swarm的发现服务,则Consul代理将把请求转发给其中一个正常运行的Consul服务器。

另一个解决scheme是在你想运行swarm worker的每台服务器上运行一个consul客户端。 然后,当你创build你的swarm工人时,只要把他们绑定到在本地机器上运行的consul代理:

 docker run -d --restart=unless-stopped --name=swarm-client \ swarm join \ --advertise=$(hostname -i):2375 \ consul://$(hostname -i):8500/ 

请注意,如果领事死在本地机器上,这将导致群集中断。

如果您在AWS中部署,则可以在ELB后注册领事服务器节点,然后将群pipe理器/节点指向ELB DNS

或者,在所有群主机上运行一个领事客户端代理,并将您的群pipe理器/节点指向consul代理,即docker0接口IP,172.17.0.1:8500