我使用位于/tmp/compose.yml
的以下docker compose文件进行docker堆栈部署:
version: "3.6"
services:
service-A:
image: service-A
networks:
- net
hostname: "service-A-{{.Task.Slot}}"
deploy:
replicas: 2
service-B:
image: service-B
networks:
- net
hostname: "service-B-{{.Task.Slot}}"
deploy:
replicas: 2
networks:
net:
运行命令:
docker network create -d overlay net
docker stack deploy -c /tmp/compose.yml my
[我的期望是service-A
个单独的容器将能够通过容器预定义的主机名service-B
发现service-B-1, service-B-2
个容器。但是,任何ping service-B-1
容器中的service-A
均失败。
Docs状态:
主机名设置容器知道其自身的主机名。这是写的进入/ etc / hostname,进入/ etc / hosts作为容器的名称面向主机的IP地址,是/ bin / bash容器将显示在其提示内。但是主机名并不容易从容器外面看。它不会出现在docker ps或在任何其他容器的/ etc / hosts文件中。
如何通过容器预定义的主机名实现docker swarm服务容器以服务容器通信?
唯一可行的方法是添加条目,如:
[service_B_container_1_virtual_ip] service-B-1
[service_B_container_2_virtual_ip] service-B-2
到/etc/hosts
个容器的service-A
。
[同样有趣的是,如果未在hostname
文件中设置docker-composes
,而是由docker生成的,即使跨多主机docker swarm,ping [container_id]
也会成功。
我希望预定义的主机名具有相同的行为。
我认为没有任何直接的方法可以做到这一点。而且我对它的思考越深,不应该进行您所要问的一种方法,就越有意义。 堆栈服务的基本特性之一是,它应以这样一种方式进行部署,即Docker能够互换对待该服务中的所有副本。如果需要连接到各个实例,则建议不要首先将这些容器创建为服务副本,因为有 something 可以ping Service-A
应该在堆栈中的任何容器中工作,ping Service-B
也应如此。 服务中各个容器的名称类似于
my_stack_redis.1.y1pwzeg8239yb6n6ynefs78br
my_stack_webserver.1.d6cxx8nlg7db9m2poy9wfjdyd
如果绝对必须从容器中访问这些名称,我能想到的唯一方法是在启动时通过绑定安装在容器内部公开/var/run/docker.sock
。然后,将套接字上的chmod 750
作为CMD / ENTRYPOINT
脚本的一部分,以便非root用户可以读取它。现在,您应该能够安装Docker CLI并使用docker network inspect
发现实际服务成员的名称,然后使用jq
解析它们(您可能需要将两个软件包都添加到映像中)。但是到那时,更好的选择可能是将那些不可替代的容器分成自己的服务组。