【发布时间】:2020-05-17 02:57:10
【问题描述】:
我有一个 3 节点的 docker swarm。
部署的一个堆栈是具有 3 个副本的数据库集群。 (MariaDB Galera)
另一个部署的堆栈是具有 2 个副本的 Web 应用程序。
Web 应用程序如下所示:
version: '3'
networks:
web:
external: true
galera_network:
external: true
services:
application:
image: webapp:latest
networks:
- galera_network
- web
environment:
DB_HOST: galera_node
deploy:
replicas: 2
FWIW,web 网络是 traefik 所连接的。
这里的问题是galera_node(用于 webapp 的数据库主机)解析为最终利用 swarm 的网状路由(据我所知)的 VIP,并且当网状路由结束时会增加额外的延迟WAN 而不是解析到部署在同一物理主机上的galera_node 容器。
我发现的另一个选项是使用tasks.galera_node,但这似乎将 DNSRR 用于 3 个 galera 集群容器。所以在 33% 的时间里,一切都很好而且很快……但在其余时间里,我增加了不必要的延迟。
这两种行为看起来被记录为我们对不同endpoint_mode 选项的期望。参考:Docker endpoint_mode
为了说明延迟,请注意从 内 webapp 容器执行 ping 操作时: 注意每次 ping 解析的 IP 地址以及响应时间。
### hitting VIP that "masks" the fact that there is extra latency
### behind it depending on where the mesh routing sends the traffic.
root@294114cb14e6:/var/www/html# ping galera_node
PING galera_node (10.0.4.16): 56 data bytes
64 bytes from 10.0.4.16: icmp_seq=0 ttl=64 time=0.520 ms
64 bytes from 10.0.4.16: icmp_seq=1 ttl=64 time=0.201 ms
64 bytes from 10.0.4.16: icmp_seq=2 ttl=64 time=0.153 ms
--- galera_node ping statistics ---
3 packets transmitted, 3 packets received, 0% packet loss
round-trip min/avg/max/stddev = 0.153/0.291/0.520/0.163 ms
### hitting DNSRR that resolves to worst latency server
root@294114cb14e6:/var/www/html# ping tasks.galera_node
PING tasks.galera_node (10.0.4.241): 56 data bytes
64 bytes from 10.0.4.241: icmp_seq=0 ttl=64 time=60.736 ms
64 bytes from 10.0.4.241: icmp_seq=1 ttl=64 time=60.573 ms
--- tasks.galera_node ping statistics ---
2 packets transmitted, 2 packets received, 0% packet loss
round-trip min/avg/max/stddev = 60.573/60.654/60.736/0.082 ms
### hitting DNSRR that resolves to local galera_node container
root@294114cb14e6:/var/www/html# ping tasks.galera_node
PING tasks.galera_node (10.0.4.242): 56 data bytes
64 bytes from 10.0.4.242: icmp_seq=0 ttl=64 time=0.133 ms
64 bytes from 10.0.4.242: icmp_seq=1 ttl=64 time=0.117 ms
--- tasks.galera_node ping statistics ---
2 packets transmitted, 2 packets received, 0% packet loss
round-trip min/avg/max/stddev = 0.117/0.125/0.133/0.000 ms
### hitting DNSRR that resolves to other "still too much" latency server
root@294114cb14e6:/var/www/html# ping tasks.galera_node
PING tasks.galera_node (10.0.4.152): 56 data bytes
64 bytes from 10.0.4.152: icmp_seq=0 ttl=64 time=28.218 ms
64 bytes from 10.0.4.152: icmp_seq=1 ttl=64 time=40.912 ms
64 bytes from 10.0.4.152: icmp_seq=2 ttl=64 time=26.293 ms
--- tasks.galera_node ping statistics ---
3 packets transmitted, 3 packets received, 0% packet loss
round-trip min/avg/max/stddev = 26.293/31.808/40.912/6.486 ms
我能够获得绕过延迟的良好性能的唯一方法是硬编码本地容器的 IP 地址,但这显然不是一个长期的解决方案,因为容器应该被视为短暂的东西。
我完全明白,由于这种延迟,我可能需要重新考虑我的地理节点位置,并且可能还有其他一些我可以做的性能调整事情。不过,似乎应该有一种方法来强制执行我想要的行为。
当本地容器可用于处理给定请求时,我基本上想绕过 DNSRR 和 VIP/mesh 路由行为。
所以问题是:
如何让我的 web 应用程序的每个副本只访问本地 swarm 主机的 galera 容器而不用硬编码该容器的 IP 地址?
【问题讨论】:
标签: docker-compose docker-swarm docker-networking