微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

dockerswarm 容器链接:“tasks.service1” vs 直接“service1”

如何解决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 举报,一经查实,本站将立刻删除。