在 Docker Swarm 中使用 Consul 进行 DNS 服务发现

在 Docker Swarm 中使用 Consul 进行 DNS 服务发现

我正在尝试使用 consul DNS 来实现服务发现。我已经设置了一个带有 consul 集群的 docker swarm,该集群充当 swarm 所需的键/值对后端,并充当其他容器的服务发现后端。

我首先从安装了 docker 引擎的 3 个裸服务器开始。我使用 ansible 配置集群。

到目前为止设置该集群的过程如下:

  • 安装docker时,--cluster-store=consul://127.0.0.1:8500在docker daemon opts中设置
  • 在“主”集群节点上,以“-bootstrap-expect 3”模式启动 consul 服务器容器
  • 在“辅助”集群节点上,以“-join”模式启动 consul 服务器容器
  • 在每个集群节点上启动一个 swarm master 和 swarm agent 容器,指向同一主机上的本地 consul 服务器

当启动 consul 服务器时,我将所有 consul 端口映射到主机,如下所示:

version: '2'

services:
    consul:
        image: progrium/consul
        hostname: "{{ ansible_hostname }}"
        ports:
            # Explanation of ports needed: http://stackoverflow.com/a/30692226/1514089
            - "8300:8300" # This is used by servers to handle incoming requests from other agents
            - "8301:8301/tcp" # This is used to handle gossip in the LAN. Required by all agents
            - "8301:8301/udp" # This is used to handle gossip in the LAN. Required by all agents
            - "8302:8302/tcp" # This is used by servers to gossip over the WAN to other servers
            - "8302:8302/udp" # This is used by servers to gossip over the WAN to other servers
            - "8400:8400" # This is used by all agents to handle RPC from the CLI
            - "8500:8500" # This is used by clients to talk to the HTTP API
            - "8600:8600" # Used to resolve DNS queries
         restart: always
         command: "{{ consul_command }}"

这让我得到了一个可以工作的docker swarm。我可以登录任何一个集群节点并使用docker compose来启动一个应用程序,swarm会透明地在服务器之间平衡。

但是现在,我想开始使用 consuls DNS 功能来解析群集中每个容器内部的服务,我希望能够执行以下操作:

$ docker run -it ubuntu dig consul.service.consul

我尝试了一些方法,但都没有成功,我怀疑这与 docker 网络有关。让我解释一下...

当我启动 consul 服务器时,它们会连接到自己的 docker-compose 网络,因为我使用 docker-compose 启动它们。但是由于 swarm 尚未运行,显然尚未设置多主机覆盖网络。因此,每个 consul 容器最终都会位于自己的主机专用桥接网络上。我只创建我的 docker 网络集群已启动。集群启动后,我无法将 consul 容器添加到覆盖网络,我得到

Error response from daemon: No such container: swarm-node-1/swarmconsul_consul_1

如何使基于 DNS 的服务发现在我的容器内发挥作用?

答案1

最后我终于让它工作了。我做错了几件事。

最大的错误是我没有将主机上的端口 53 映射到 consul 容器内的端口 53/udp。完整的端口映射现在如下所示:

services:
    consul:
        image: progrium/consul
        hostname: "{{ ansible_hostname }}"
        ports:
          # Explanation of ports needed: http://stackoverflow.com/a/30692226/1514089
          - "8300:8300" # This is used by servers to handle incoming requests from other agents
          - "8301:8301/tcp" # This is used to handle gossip in the LAN. Required by all agents
          - "8301:8301/udp" # This is used to handle gossip in the LAN. Required by all agents
          - "8302:8302/tcp" # This is used by servers to gossip over the WAN to other servers
          - "8302:8302/udp" # This is used by servers to gossip over the WAN to other servers
          - "8400:8400" # This is used by all agents to handle RPC from the CLI
          - "8500:8500" # This is used by clients to talk to the HTTP API
          - "8600:8600" # Used to resolve DNS queries
          - "172.17.0.1:53:53/udp"
        restart: always
        command: "{{ consul_command }}"

这里我们绑定到 docker0 接口上的端口 53。但是,我了解到 docker0 网桥的 IP 可以更改,因此我对其进行了一些硬编码,并通过在--bip=172.17.0.1docker 守护进程选项中指定来告诉 docker 始终将此 IP 用于 docker0 网桥。下一步是将 docker 守护进程的默认 dns 设置为相同的 IP。我的完整 docker 守护进程选项如下所示:

[Service]
ExecStart=
ExecStart=/usr/bin/docker daemon \
    -H tcp://0.0.0.0:2375 \
    -H unix:///var/run/docker.sock \
    --bip=172.17.0.1/16 \
    --dns=172.17.0.1 \
    --dns-search=service.consul \
    --storage-driver=overlay \
    --cluster-store=consul://127.0.0.1:8500

现在我可以这样做:

$ sudo docker -H :4000 run -it joffotron/docker-net-tools
/ # dig +short consul.service.consul
10.0.0.93
10.0.0.95
10.0.0.94

伟大的!

相关内容