如何解决dockerswarm 容器链接:“tasks.service1” vs 直接“service1”
使用 docker swarm 时,在 curling/ping 时使用“tasks.service1”或直接使用“service1”有什么区别?
实际例子: 我在同一个覆盖网络上启动了一个 docker swarm 服务,如下所示:
$> docker network create --driver=overlay public
$> docker service create --name service1 --replicas=2 --network public ubuntu sleep 10000
现在我列出容器:
$> docker ps -a
bd645378cb2d ubuntu:latest "sleep 10000" 43 seconds ago Up 41 seconds service1.1.rjy91s66col81libdilrd698j
686c0ab006fc ubuntu:latest "sleep 10000" 43 seconds ago Up 41 seconds service1.2.wjrwsj6h6rcadsknzxym4h9w0
如果我附加到第一个容器,我可以 ping 其他容器:
$> docker exec -ti bd645378cb2d bash
$> apt update
$> apt install iputils-ping dnsutils
$> ping service1 # returns ok 10.0.1.65
当我挖掘特殊主机名 tasks.service1 时,我得到所有副本 ips。 但是这些论文与我通过 ping 得到的论文不匹配。
$> dig tasks.service1 # returns 10.0.1.66 & 10.0.1.67
为什么ips不匹配? 如果我需要从服务 1 连接到服务 2,我应该使用 tasks.service2 还是 service2 ?
解决方法
这是一个负载均衡器 IP。如果使用默认 vip
(虚拟 IP)--endpoint-mode
创建,则 Docker 服务具有它。你可以用docker inspect <service_name>
查看:
"Endpoint": {
"Spec": {
"Mode": "vip"
},"VirtualIPs": [
{
"NetworkID": "i7k7pv9s4v7dgvc57zjmh6pk6","Addr": "10.0.1.2/24"
}
]
}
这在 documentation 中有提到,虽然很容易忽略这一点:
要使用没有路由网格的外部负载均衡器,请将 --endpoint-mode 设置为 dnsrr
,而不是默认值 vip
。在这种情况下,没有一个虚拟 IP。
tasks.service1
名称将解析为服务中每个单独容器的 IP 地址。如果您需要引用单个副本,这会很有用。
但是,有一个缺点。大多数操作系统和应用程序中的 DNS 缓存。这意味着在更新您的服务期间,陈旧的 DNS 解析可能指向一个不再可访问的 IP,或者可能指向一个最近使用回收 IP 启动的完全不同的容器。
要在 Swarm 模式下处理此问题,解析 service1
时默认使用虚拟 IP (VIP)。这会随着副本的创建/删除而动态更新,而不会出现 DNS 缓存问题。它对每个新连接执行循环负载平衡。
旁注,这也被已发布端口上的入口使用。这意味着,如果您有一个指向集群的外部 LB,一个在入口发布的端口,指向全局调度服务,那么您最终可能会得到一个额外的网络跃点。在这些情况下,我通常会绕过 VIP,以主机模式发布端口,并让外部 LB 将请求定向到集群中的不同节点。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。