Docker Swarm服务间通信是否通过路由网?

Docker Swarm服务间通信是否通过路由网?,docker,routing,docker-swarm,docker-networking,Docker,Routing,Docker Swarm,Docker Networking,如果我有一个多节点Docker Swarm,连接到一个用户定义的覆盖网络,并且服务a尝试与服务B通信,其中服务B有多个副本,哪个副本将获得消息?我意识到路由网格是一个入口,但在这种情况下也需要发生类似的事情,对吗?基本上,有两种端点模式: dnsrr=>服务DNS解析容器IP 默认值=>服务DNS解析群集入口路由器 Swarm路由器是一个纯粹的******,它有很多网络问题(超时,没有到主机的路由,僵尸) dnsrr将提供所有容器IP,这很酷,但这可能会导致DNS缓存出现问题(logstas

如果我有一个多节点Docker Swarm,连接到一个用户定义的覆盖网络,并且服务a尝试与服务B通信,其中服务B有多个副本,哪个副本将获得消息?我意识到路由网格是一个入口,但在这种情况下也需要发生类似的事情,对吗?

基本上,有两种端点模式:

  • dnsrr
    =>服务DNS解析容器IP
  • 默认值
    =>服务DNS解析群集入口路由器
Swarm路由器是一个纯粹的******,它有很多网络问题(超时,没有到主机的路由,僵尸)

dnsrr
将提供所有容器IP,这很酷,但这可能会导致DNS缓存出现问题(logstash、Php AMQP客户端…):

“服务A有X秒的DNS缓存,它可以与容器B.1通信。容器B.1崩溃,使用不同的IP重新生成==>服务A仍然发送到以前的IP”


对于具有多个网络的容器也要小心。

基本上,有两种端点模式:

  • dnsrr
    =>服务DNS解析容器IP
  • 默认值
    =>服务DNS解析群集入口路由器
Swarm路由器是一个纯粹的******,它有很多网络问题(超时,没有到主机的路由,僵尸)

dnsrr
将提供所有容器IP,这很酷,但这可能会导致DNS缓存出现问题(logstash、Php AMQP客户端…):

“服务A有X秒的DNS缓存,它可以与容器B.1通信。容器B.1崩溃,使用不同的IP重新生成==>服务A仍然发送到以前的IP”


对于具有多个网络的容器也要小心。

默认情况下,docker使用内核中使用的虚拟IP(VIP)配置每个服务。这将在每个不同网络连接的每个服务副本之间执行循环负载平衡(在TCP连接的生命周期内,持久网络连接将保持连接到同一副本)

当转发到的IP地址位于另一个节点上时,它使用覆盖网络(由内核中的vxlan实现)将这些数据包发送到其他节点。如果网络上有任何东西阻塞了覆盖网络端口,您将看到使其正常工作的问题。Docker在其文档中有以下内容:

  • 用于群集管理通信的TCP端口2377
  • 用于节点间通信的TCP和UDP端口7946
  • 覆盖网络流量的UDP端口4789
我经常在每个节点上使用tcpdump调试连接问题,以查看从一个节点发送的数据包是否在目的地收到。如有必要,在初始化swarm群集时,可以使用
docker swarm init--data path port
标志更改覆盖端口

我更喜欢在大多数情况下使用默认的覆盖网络,因为它消除了一类DNS缓存问题。如果使用DNS循环,swarm群集中的每个容器都可以缓存服务副本的DNS结果,并与该服务使用的旧IP地址通信,只要DNS缓存结果在该容器的应用程序中保持不变。当您等待应用程序刷新选定容器的DNS结果时,这可能会导致滚动更新期间出现大量停机。虽然我在过去遇到过IPV的问题,但在最新版本的docker中,我没有遇到过具有较新内核的问题,而且许多kubernetes网络提供商现在使用相同的内核模块,这导致了更多的测试和稳定性

如果要获取服务副本的单个IP地址,或使用DNS RR,则可以一次性完成此操作,而无需禁用服务VIP。相反,如果要查询web服务的VIP的
web
,则可以查询该服务的所有副本的DNS RR的
tasks.web
(将
web
替换为您的服务名称)。我只在应用程序需要对每个副本运行命令时才这样做,并且我可以看到它对粘性会话有多大用处

至于这与入口网络和服务网格的关系,入口网络被配置为将特定端口路由到集群中每个节点入口网络上的VIP。当您在网络上运行
docker network inspect-v…
时,您将看到服务连接到的每个覆盖网络的VIP,包括入口网络(如果您有已发布的端口)


<> P>我认为禁用入口网络的唯一时间是,如果我有一个全局服务,一个节点集群,或者一个在一个可预测的节点列表上运行的服务,并且我希望避免由服务网格添加的额外的网络跳跃。在这些场景中,我以“主机”模式发布端口(有关发布端口的信息,请参阅)。这将阻止您在一个节点上运行多个副本,但在我的大多数使用案例中,这适用于多个副本没有意义的有状态应用程序。

默认情况下,docker使用内核中使用的虚拟IP(VIP)配置每个服务。这将在每个不同网络连接的每个服务副本之间执行循环负载平衡(在TCP连接的生命周期内,持久网络连接将保持连接到同一副本)

当转发到的IP地址位于另一个节点上时,它使用覆盖网络(由内核中的vxlan实现)将这些数据包发送到其他节点。如果网络上有任何东西阻塞了覆盖网络端口,您将看到使其正常工作的问题。Docker在其文档中有以下内容:

  • 用于群集管理通信的TCP端口2377
  • 用于节点间通信的TCP和UDP端口7946
  • 覆盖网络流量的UDP端口4789