gpt4 book ai didi

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

转载 作者:行者123 更新时间:2023-12-03 14:40:06 27 4
gpt4 key购买 nike

我正在使用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世界?

最佳答案

Docker的内置Nameserver和Loadbalancer
Docker带有内置的名称服务器。默认情况下,可通过127.0.0.11:53访问该服务器。
默认情况下,每个容器在/etc/resolve.conf中都有一个名称服务器条目,因此不需要从容器内指定名称服务器的地址。
这就是为什么您可以使用servicestack_service_n在网络中找到您的服务的原因。
如果执行stack_service_n,则将获得相应服务副本的地址。
如果仅要求service,则docker 将由执行internal load balancing
使用swarm时,docker将另外使用ingress network提供external load balancing,该dig允许从swarm中的任何节点查询任何服务。
当使用swarm到deploy时,除非将端点模式设置为dns roundrobin而不是vip,否则以下示例中描述的默认行为将不起作用。

endpoint_mode: vip - Docker assigns the service a virtual IP (VIP) that acts as the front end for clients to reach the service on a network. Docker routes requests between the client and available worker nodes for the service, without client knowledge of how many nodes are participating in the service or their IP addresses or ports. (This is the default.)


endpoint_mode: dnsrr - DNS round-robin (DNSRR) service discovery does not use a single virtual IP. Docker sets up DNS entries for the service such that a DNS query for the service name returns a list of IP addresses, and the client connects directly to one of these. DNS round-robin is useful in cases where you want to use your own load balancer, or for Hybrid Windows and Linux applications.


例子
例如,从dig/docker-compose.yml部署三个副本
version: '3.8'
services:
whoami:
image: "traefik/whoami"
deploy:
replicas: 3
DNS查询
回答您的问题如何找到所有的容器。您可以使用 nslookup+short之类的工具针对同一网络中的名称服务器进行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感兴趣,则可以提供 task.<servicename>选项
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
虫群的例子
正如最初提到的,群集的行为有所不同,因为默认情况下它将为服务分配虚拟IP。它实际上没有什么不同,只是docker或docker-compose不会创建真实的服务,它只是模仿swarm的行为,但仍运行容器常规设置,因为服务实际上只能由管理器节点创建。
请记住,我们正在使用集群管理器,因此默认模式为VIP
创建一个也可以由常规容器使用的覆盖网络
$ docker network create --driver overlay --attachable testnet
用2个副本创建一些服务
$ docker service create --network testnet --replicas 2 --name digme nginx
现在,让我们再次使用dig,并确保将容器连接到同一网络
$ docker run --network testnet --rm tutum/dnsutils dig  digme
digme. 600 IN A 10.0.18.6
我们看到确实只有一个IP地址,所以看来这是docker分配的虚拟IP。
Swarm实际上允许在这种情况下获得单个IP地址 ,而无需显式设置端点模式。
在这种情况下,我们可以查询 tasks.digme
$ docker run --network testnet --rm tutum/dnsutils dig tasks.digme
tasks.digme. 600 IN A 10.0.18.7
tasks.digme. 600 IN A 10.0.18.8
这给我们带来了指向各个副本的2 A记录。
现在让我们创建一个将endpointmode设置为dns roundrobin的服务
docker service create --endpoint-mode dnsrr --network testnet --replicas 2 --name digme2 nginx
$ docker run --network testnet --rm tutum/dnsutils dig digme2
digme2. 600 IN A 10.0.18.21
digme2. 600 IN A 10.0.18.20
这样,我们无需获得前缀 tasks即可获得两个IP。
现代服务发现
综上所述,这并不是报价现代服务发现报价的真正方式。这是像 traefik这样的项目开始起作用的地方。
而且,如今,更多的传统代理很好地支持容器。例如,HAProxy在容器周围具有 since 1.8的许多不错的功能,例如动态cookie,服务模板和docker名称服务器的一流集成。
您也可以将配置自动化与 consulzookeper之类的东西集成在一起。

关于docker - 服务发现如何与现代docker/docker-compose一起使用?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37683508/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com