在我的 博客 我探索了与MarkH的答案类似的方法,但关键的区别在于,我指的是加入网络的前三个节点,而不是指向新服务器的VIP。这可能是有益的,因为VIP存在问题,它将指向自身与在该VIP上的所有节点上的负载平衡。根据我的经验,最好以这种方式为服务创建。
docker service create \ --network=consul \ --name=consul \ -e 'CONSUL_LOCAL_CONFIG={"skip_leave_on_interrupt": true}' \ -e CONSUL_BIND_INTERFACE='eth0' \ --mode global \ -p 8500:8500 \ consul agent -server -ui -client=0.0.0.0 \ -bootstrap-expect 3 \ -retry-join 172.20.0.3 \ -retry-join 172.20.0.4 \ -retry-join 172.20.0.5 \ -retry-interval 5s
我在3节点群中使用全局模式,因此您可以将其交换为副本并放置约束。
经过深思熟虑和许多死胡同,我们终于想出了一个适合我们的解决方案。问题的一部分在于,在编写本文时,Docker 1.12有些少年,并且在它有意义之前引入了许多必须被理解的概念。在我们的例子中,我们之前使用Swarm 1.12变体的经验阻碍了我们的前瞻性思维而不是帮助。
我们用于为我们的群体部署consul K / V服务的解决方案如下
创建一个名为“consul”的覆盖网络。这为我们的服务创建了一个地址空间。
docker network create --driver overlay --subnet 10.10.10.0/24 consul
将consul服务器群集部署到新的覆盖中。我们有三个主机用作管理器节点,我们希望consul服务器容器在这个集群而不是app服务器上运行,因此'constraint'标志
docker service create -e 'CONSUL_LOCAL_CONFIG={"leave_on_terminate": true}' --name consulserver --network consul --constraint 'node.role == manager' --replicas 3 consul agent server -bootstrap-expect=3 -bind=0.0.0.0 -retry-join="10.10.10.2" -data-dir=/tmp
这里的关键是swarm将在领事网络的开头分配一个新的VIP(10.10.10.2),映射到三个新实例。
接下来,我们部署了代理服务
docker service create \ -e 'CONSUL_BIND_INTERFACE=eth0' \ -e 'CONSUL_LOCAL_CONFIG={"leave_on_terminate": true, "retry_join":["10.10.10.2"]}' \ --publish "8500:8500" \ --replicas 1 \ --network consul \ --name consulagent \ --constraint 'node.role != manager' \ consul agent -data-dir=/tmp -client 0.0.0.0
指定consulserver服务的VIP。 (领事不会解析加入的名称 - 其他容器可能做得更好,允许指定服务名称“consulserver”而不是VIP)
这样做,任何其他服务可以通过加入领事网络并解析名称“consulagent”来访问consiggent。可以根据需要缩放(或者可以部署为全局服务)顾问服务。 发布端口8500使服务在群集边缘可用,如果您不需要将其提供给非群集服务,则可以将其丢弃。
对于像我这样喜欢从docker-compose.yml文件运行我们的服务的人,我设法“docker stack deploy”
https://github.com/thechane/consul/blob/master/docker-compose.yml
...将Consul作为Docker服务运行。
---编辑,糟糕的形式,只需回答链接所以这里是:
version: '3.1' #customise this with options from #https://www.consul.io/docs/agent/options.html services: seed: hostname: seed image: consul:0.8.0 deploy: restart_policy: condition: none #we do not want this to be restarted on timeout (see entrypoint options below) replicas: 1 placement: constraints: - "engine.labels.access == temp" - "engine.labels.access != consul" environment: - "CONSUL_LOCAL_CONFIG={\"disable_update_check\": true}" - "CONSUL_BIND_INTERFACE=eth0" entrypoint: - timeout #this seed fires up the cluster after which it is no longer needed - -sTERM #this is the same signal as docker would send on a scale down / stop - -t300 #terminate after 5 mins - consul - agent - -server - -bootstrap-expect=5 - -data-dir=/tmp/consuldata - -bind={{ GetInterfaceIP "eth0" }} networks: - "consul" cluster: image: consul:0.8.0 depends_on: - "seed" deploy: mode: global ##this will deploy to all nodes that placement: constraints: - "engine.labels.access == consul" ##have the consul label - "engine.labels.access != temp" environment: - "CONSUL_LOCAL_CONFIG={\"disable_update_check\": true}" - "CONSUL_BIND_INTERFACE=eth0" - "CONSUL_HTTP_ADDR=0.0.0.0" entrypoint: - consul - agent - -server - -data-dir=/tmp/consuldata - -bind={{ GetInterfaceIP "eth0" }} - -client=0.0.0.0 - -retry-join=seed:8301 - -ui ##assuming you want the UI on networks: - "consul" ports: - "8500:8500" - "8600:8600" networks: consul: driver: overlay
还要注意,我后来发现,如果没有种子,就不能添加更多的consul实例。因此,如果您打算扩展您的swarm节点计数,我将从种子入口点删除带有其选项的timeout命令。
令人困惑的是Docker“Swarm Mode”实际上是一种不同的动物,它仍然被称为Docker Swarm。在群体模式中,您不需要领事。每个主机上的docker守护程序充当键值存储并执行服务发现。它为“旧”Docker Swarm中的Consul所需的一切做了。
请注意查找仅针对“群集模式”的文档/信息。我希望他们实际上使用了不同的名字。