问题描述
我有一个包含2个节点的docker群,每个节点在全局模式下运行2个服务,因此每个节点内部都运行2个服务。
我的问题是如何强制node1中的ubuntu服务仅连接到node1中的MysqL服务,而不使用轮询方法选择MysqL服务。
因此,当我使用MysqL -hMysqL -uroot -p
从node1中的ubuntu连接到MysqL时,它仅选择node1中的MysqL。
这是描述我的情况的docker-compose文件
version: '3.8'
services:
MysqL:
image: MysqL:5.7
environment:
MysqL_ROOT_PASSWORD: password
networks:
app-net: {}
deploy:
mode: global
ubuntu:
entrypoint: tail -f /dev/null
deploy:
mode: global
image: ubuntu:20.04
networks:
app-net: {}
networks:
app-net: {}
在我尝试连接到MysqL时,在ubuntu容器中使用这个docker-compose文件,它使用轮询算法在两个节点中选择MysqL服务。 我试图实现的是强制每个服务仅对同一节点内的服务可见。
解决方法
我想不出一种简单的方法来通过覆盖网络来实现您想要的目标。但是,您可以使用unix套接字而不是网络。只需创建一个卷,将其安装到MySQL和应用程序中,然后使MySQL将其套接字放置到该卷上即可。 Docker将在每个节点上创建一个卷,因此您将在节点内关闭通信。
如果您坚持使用网络通信,则可以将节点的Docker套接字安装到您的应用容器中,并使用它来查找在该节点上运行MySQL的容器的名称。一旦获得名称,就可以使用它来连接到服务的特定实例。现在,这不仅很难制造,而且是一种反模式和一种安全威胁,所以我不建议您实施这种想法。
最后还有Kubernetes,一个pod内的容器可以通过localhost相互通信,但是我想你不会走那么远,对吗?
,您应该看看mode=host。
您可以绕过路由网格,以便在访问给定节点上的绑定端口时,始终可以访问在该节点上运行的服务的实例。这称为主机模式。有几件事要牢记。
ports:
- target: 80
published : 8080
protocol: tcp
mode: host
,
除非我丢失了某些东西,否则我会说您不应该使用全局部署,而应该在撰写文件中声明2个ubuntu服务和2个mysql服务,或者部署2个单独的堆栈,并且在两种情况下都使用约束将容器固定到特定节点
第一种情况的示例如下:
version: '3.8'
services:
mysql1:
image: mysql:5.7
environment:
MYSQL_ROOT_PASSWORD: password
deploy:
placement:
constraints: [node.hostname == node1]
mysql2:
image: mysql:5.7
environment:
MYSQL_ROOT_PASSWORD: password
deploy:
placement:
constraints: [node.hostname == node2]
ubuntu1:
entrypoint: tail -f /dev/null
image: ubuntu:20:04
deploy:
placement:
constraints: [node.hostname == node1]
ubuntu2:
entrypoint: tail -f /dev/null
image: ubuntu:20:04
deploy:
placement:
constraints: [node.hostname == node2]