如何改善或调试Docker覆盖网络的弹性?

dev*_*bot 5 networking docker openvswitch weave

背景

我们维护运行生产应用程序的Ubuntu主机的“集群”。主机运行各种各样的Docker容器,例如

  • 容器监控和普罗米修斯服务发现领事
  • 具有多个logstash和kibana的Elasticsearch集群
  • 普罗米修斯
  • 格拉那
  • 内部开发的应用程序(下图中的服务A到K)

每个主机也运行

  • 文件拍
  • Nginx的
  • 保持活力
  • Docker Overlay Network的领事

设置如下: 码头工人覆盖网络

图片信息

  • 主机领事公开2xxx而不是标准8xxx中的端口
  • 并非所有Docker容器都暴露于外界,例如elasticsearch-slave1没有暴露的端口,但内部使用的端口显示为:9200
  • docker consul使用覆盖网络进行所有通信,并且只有consul-masterHost1上的端口8500对外暴露了端口。

组态

其中一些信息可能与该问题完全无关。

主持人:Ubuntu 16.04.3 LTS

主机服务 | Application | Version | | ----------- | ---------- | | docker | 18.03.1-ce | | consul | v1.0.2 | Docker服务 | Application | Version | | ------------- | ------- | | consul | v1.0.2 | | elasticsearch | 5.6.4 | | logstash | 5.6.4 | | kibana | 5.6.4 | | prometheus | 2.0.0 |

docker.service

每个主机上的Docker配置如下: [Service] ExecStart=/usr/bin/dockerd -H fd:// -H tcp://0.0.0.0:2375 -H unix:///var/run/docker.sock --cluster-advertise ${THIS_MACHINES_IP}:2375 --cluster-store consul://${THIS_MACHINES_IP}:2500 --label com.domain.hostname=host05.domain.com

问题

当我们首次部署此配置时,它的运行非常出色。但是随着时间的流逝,码头工人覆盖网络变得越来越不可靠。HostX上的容器将完全无法使用覆盖网络与HostY上的其他容器进行通信

例如,prometheus在Host5 service A上会从Host1 上抓取信息,但会经常报告“ no route to host”或“ context deadline exceeded”。如果我docker exec进入prometheus容器并尝试ping或卷曲,service A我只会收到超时。但是,如果我docker exec进入service A并尝试对prometheus数据包执行ping和卷曲操作,这似乎会“唤醒”网络。现在prometheus可以再次看到该服务。

多个服务之间会发生相同的问题-这经常导致logstash无法发布elasticsearchelasticsearch-master无法联系,slaves从而破坏了群集。

因为此设置正在我们的生产环境中积极使用,所以我们无法承受这样的网络停机时间。我实现了一组计划的作业,这些作业在各种服务之间卷曲/平移,以保持网络正常运行。这显然不是一个好的长期解决方案!

使情况变得更糟的是,有时网络变得如此糟糕,以至于curl / ping作业无济于事,并且重启主机或泊坞窗没有任何效果。我发现的唯一解决方案是

  • 创建一个新的temporary overlay网络
  • 从断开每个容器的primary overlay连接,然后将它们连接到temporary overlay
  • 删除 primary overlay
  • 创建一个新的 primary overlay
  • 从断开每个容器的temporary overlay连接,然后将它们连接到primary overlay
  • 删除 temporary overlay

到目前为止,这种方法是我找到的完全恢复网络的最佳解决方案。然后它将运行良好一段时间,然后再次掉落。

问题

对我来说,最迫切的问题是如何调试此问题并找到根本原因?

有一些人经历过此问题,但通常是在较小的设置中,并且规模与上述不同。此刻,我好像正在运行Schrodinger的网络...

其次- 是否有更好的方法来实现覆盖网络?

我已经开始与试验weaveOpen vSwitch但也不是替代不错滴当前网络。

编织将需要重新部署所有容器(可能的话),但是它向每个容器添加了辅助网络接口,并且该ethwe接口不是主要接口,它导致问题consulprometheus绑定到特定接口/地址。

Open vSwitch似乎是替代产品,但我无法使其与LTS版本(2.5.x)配合使用,因此必须从源代码构建2.10.x。这似乎起初elasticsearch是可行的,但不能集群化,而且consul似乎很难通过网络进行通信。prometheusconsul由于某种原因无法查询。我假设交换机丢弃了一些数据包,这可能只是配置问题。

编辑-28/09/2018

自发布此问题以来,我一直在测试使用Docker Swarm来管理覆盖网络。

到目前为止,它运行良好,并且网络不会像使用领事群集存储时那样随机地停止工作。但是,存在一些关键差异和一些常见故障。例如:

  • docker network inspect <my overlay network>在主机上执行只会显示在该主机上运行的容器。将Consul用作群集存储时,您可以从任何主机查看整个网络。
  • 仍然有可能使网络陷入容器无法互相看到的错误状态。这可以通过相对快速地停止,删除和重新创建容器(与以前的名称相同)来实现。在这种情况下,现有容器将继续使用旧的 DNS条目,并且无法连接。