如何使用 Docker 1.12 swarm 模式部署 consul
How to deploy consul using Docker 1.12 swarm mode
我有一个包含 3 个服务器的 consul 集群。我还有一个 docker 群,大约有 6 个工人和 3 个主人(主人与领事服务器在同一硬件上,但设置了可用性 == 耗尽以防止他们接受工作)。
我一般使用consul-template来读取consulK/V。我一辈子都想不出如何明智地推出领事代理服务。如果我使用全局服务,那么每个节点都有一个代理,但服务器集群会抱怨,因为客户端代理似乎都具有相同的 IP 地址。
复制服务似乎是可行的方法,但我相信我需要发布客户端端口 8301,这似乎会导致与我的服务器集群(运行 swarm master 和 consul 发生冲突服务器(不在 docker 之下)。
我希望能在正确的方向上进行总体引导 - 请记住这是 1.12 集群模式,因此与早期版本有很大不同。
这很令人困惑,但 Docker "Swarm Mode" 确实是一种与仍被称为 Docker 群的动物不同的动物。在 Swarm 模式下你不需要 Consul。每个主机上的 docker 守护进程充当键值存储并进行服务发现。它可以满足 "old" Docker Swarm 中 Consul 的所有需求。
请注意查找仅特定于 "swarm mode" 的 documentation/info。我希望他们实际上使用了不同的名称。
经过深思熟虑和许多死胡同,我们终于想出了一个适合我们的解决方案。部分问题在于,在撰写本文时,Docker 1.12 还有些幼稚,并且引入了许多概念,在它变得有意义之前必须先理解这些概念。在我们的案例中,我们之前使用 Swarm 1.12 之前版本的经验阻碍了我们的前瞻性思考,而不是帮助了我们。
我们用来为 swarm 部署 consul K/V 服务的解决方案如下
创建一个名为 'consul' 的覆盖网络。这会创建一个地址 space 供我们的服务在其中运行。
docker network create --driver overlay --subnet 10.10.10.0/24 consul
将 consul 服务器集群部署到新覆盖层中。我们有三个主机用作管理器节点,我们希望 consul 服务器容器在这个集群上 运行 而不是应用程序服务器,因此 '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 会在映射到三个新实例的 consul 网络的起始处分配一个新的 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。 (Consul 不会为加入解析名称 - 其他容器可能会做得更好,允许指定服务名称 "consulserver" 而不是 VIP)
完成后,任何其他服务都可以通过加入 consul 网络并解析名称 "consulagent" 来访问 consulagent。 consulagent 服务可以根据需要扩展(或部署为全球服务)。
发布端口 8500 使该服务在 swarm 边缘可用,如果您不需要使其对非 swarm 服务可用,则可以将其删除。
在我的 blog 中,我探索了与 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-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
另外注意,后来我发现没有seed就无法添加更多的consul实例。因此,如果您打算扩展集群节点数,我会从种子入口点删除超时命令及其选项。
我有一个包含 3 个服务器的 consul 集群。我还有一个 docker 群,大约有 6 个工人和 3 个主人(主人与领事服务器在同一硬件上,但设置了可用性 == 耗尽以防止他们接受工作)。
我一般使用consul-template来读取consulK/V。我一辈子都想不出如何明智地推出领事代理服务。如果我使用全局服务,那么每个节点都有一个代理,但服务器集群会抱怨,因为客户端代理似乎都具有相同的 IP 地址。
复制服务似乎是可行的方法,但我相信我需要发布客户端端口 8301,这似乎会导致与我的服务器集群(运行 swarm master 和 consul 发生冲突服务器(不在 docker 之下)。
我希望能在正确的方向上进行总体引导 - 请记住这是 1.12 集群模式,因此与早期版本有很大不同。
这很令人困惑,但 Docker "Swarm Mode" 确实是一种与仍被称为 Docker 群的动物不同的动物。在 Swarm 模式下你不需要 Consul。每个主机上的 docker 守护进程充当键值存储并进行服务发现。它可以满足 "old" Docker Swarm 中 Consul 的所有需求。
请注意查找仅特定于 "swarm mode" 的 documentation/info。我希望他们实际上使用了不同的名称。
经过深思熟虑和许多死胡同,我们终于想出了一个适合我们的解决方案。部分问题在于,在撰写本文时,Docker 1.12 还有些幼稚,并且引入了许多概念,在它变得有意义之前必须先理解这些概念。在我们的案例中,我们之前使用 Swarm 1.12 之前版本的经验阻碍了我们的前瞻性思考,而不是帮助了我们。
我们用来为 swarm 部署 consul K/V 服务的解决方案如下
创建一个名为 'consul' 的覆盖网络。这会创建一个地址 space 供我们的服务在其中运行。
docker network create --driver overlay --subnet 10.10.10.0/24 consul
将 consul 服务器集群部署到新覆盖层中。我们有三个主机用作管理器节点,我们希望 consul 服务器容器在这个集群上 运行 而不是应用程序服务器,因此 '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 会在映射到三个新实例的 consul 网络的起始处分配一个新的 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。 (Consul 不会为加入解析名称 - 其他容器可能会做得更好,允许指定服务名称 "consulserver" 而不是 VIP)
完成后,任何其他服务都可以通过加入 consul 网络并解析名称 "consulagent" 来访问 consulagent。 consulagent 服务可以根据需要扩展(或部署为全球服务)。 发布端口 8500 使该服务在 swarm 边缘可用,如果您不需要使其对非 swarm 服务可用,则可以将其删除。
在我的 blog 中,我探索了与 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-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
另外注意,后来我发现没有seed就无法添加更多的consul实例。因此,如果您打算扩展集群节点数,我会从种子入口点删除超时命令及其选项。