服务发现如何与现代docker / docker-compose一起使用?

时间:2016-06-07 15:29:09

标签: docker docker-compose service-discovery

我正在使用Docker 1.11.1和docker-compose 1.8.0-rc2。

在过去的好时光(去年),您可以设置docker-compose.yml这样的文件:

app:
  image: myapp

frontend:
  image: myfrontend
  links:
    - app

然后启动这样的环境:

docker scale app=3 frontend=1

您的前端容器可以检查环境变量 对于名为APP_1_PORTAPP_2_PORT等的变量来发现 可用的后端主机并相应地配置自己。

时代变了。现在,我们这样做......

version: '2'

services:
  app:
    image: myapp

  frontend:
    image: myfrontend
    links:
      - app

...而不是环境变量,我们得到DNS。所以在里面 frontend容器,我可以要求app_app_1app_app_2app_app_3并获取相应的IP地址。我也可以要求 app并获取app_app_1的地址。

但是如何发现所有可用的后端容器?一世 我想我可以循环getent hosts ...直到它失败:

counter=1
while :; do
  getent hosts app_$counter || break
  backends="$backends app_$counter"
  let counter++
done

但这看起来很丑陋而且很脆弱。

我听说过关于循环dns的传闻,但(a)似乎没有 在我的测试环境中发生,(b)不一定 如果您的前端需要同时连接到后端,请提供帮助。

简单的容器和服务发现如何在工作中发挥作用 现代Docker世界?

1 个答案:

答案 0 :(得分:1)

Docker内置的Nameserver和Loadbalancer

Docker带有内置的名称服务器。默认情况下,可以通过127.0.0.11:53访问该服务器。

默认情况下,每个容器在/etc/resolve.conf中都有一个名称服务器条目,因此不需要从容器内指定名称服务器的地址。

这就是为什么您可以使用servicestack_service_n在网络中找到服务的原因。

如果您执行stack_service_n,则将获得相应服务副本的地址。

如果您只要求service码头工人执行internal load balancing

使用群集时,docker将另外使用ingress network提供external load balancing,以允许从群集中的任何节点查询任何服务。

在将swarm用于deploy时,除非将endpointmode设置为dns roundrobin而不是vip,否则以下示例中所述的默认行为将无效。

endpoint_mode:vip-Docker为该服务分配一个虚拟IP(VIP),该虚拟IP充当客户端访问网络上服务的前端。 Docker在客户端和服务的可用工作节点之间路由请求,而无需客户端知道有多少节点正在参与服务或其IP地址或端口。 (这是默认设置。)

endpoint_mode:dnsrr-DNS循环(DNSRR)服务发现不使用单个虚拟IP。 Docker设置服务的DNS条目,以便对服务名称的DNS查询返回IP地址列表,并且客户端直接连接到其中之一。在想要使用自己的负载平衡器或混合Windows和Linux应用程序的情况下,DNS轮询很有用。

示例

例如,从 dig / docker-compose.yml

部署三个副本
version: '3.8'
services:
  whoami:
    image: "traefik/whoami"
    deploy:
      replicas: 3

DNS查找

回答您的问题如何找到所有容器。您可以使用诸如dignslookup之类的工具针对同一网络中的名称服务器进行DNS查找。

docker run --rm --network dig_default tutum/dnsutils dig whoami
; <<>> DiG 9.9.5-3ubuntu0.2-Ubuntu <<>> whoami
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 58433
;; flags: qr rd ra; QUERY: 1, ANSWER: 3, AUTHORITY: 0, ADDITIONAL: 0

;; QUESTION SECTION:
;whoami.                                IN      A

;; ANSWER SECTION:
whoami.                 600     IN      A       172.28.0.3
whoami.                 600     IN      A       172.28.0.2
whoami.                 600     IN      A       172.28.0.4

;; Query time: 0 msec
;; SERVER: 127.0.0.11#53(127.0.0.11)
;; WHEN: Mon Nov 16 22:36:37 UTC 2020
;; MSG SIZE  rcvd: 90

如果您只对IP感兴趣,则可以提供+short选项

docker run --rm --network dig_default tutum/dnsutils dig +short whoami
172.28.0.3
172.28.0.4
172.28.0.2

或寻找特定服务

docker run --rm --network dig_default tutum/dnsutils dig +short dig_whoami_2
172.28.0.4

负载均衡

接下来,通过curl测试内置的负载均衡器。重复此命令几次,然后观察主机名和IP地址的更改。

docker run --rm --network dig_default curlimages/curl -Ls http://whoami
Hostname: eedc94d45bf4
IP: 127.0.0.1
IP: 172.28.0.3
RemoteAddr: 172.28.0.5:43910
GET / HTTP/1.1
Host: whoami
User-Agent: curl/7.73.0-DEV
Accept: */*

这是10次curl中的主机名:

Hostname: eedc94d45bf4
Hostname: 42312c03a825
Hostname: 42312c03a825
Hostname: 42312c03a825
Hostname: eedc94d45bf4
Hostname: d922d86eccc6
Hostname: d922d86eccc6
Hostname: eedc94d45bf4
Hostname: 42312c03a825
Hostname: d922d86eccc6

现代服务发现

这一切都说明了,这并不是报价现代服务发现中报价的真正方式。这就是traefik之类的项目开始发挥作用的地方。

如今,更多传统的代理很好地支持容器。例如,HAProxy在容器周围具有since 1.8的许多不错的功能,例如动态cookie,服务模板和docker名称服务器的一流集成。

您还可以将配置自动化与consulzookeper之类的东西集成在一起。