Docker服务在一段时间后停止通信

我有6个容器在docker群中运行。 Kafka + Zookeeper,MongoDB,A,B,C和界面。 接口是公共的主要接入点 – 只有这个容器发布端口 – 5683.接口容器在启动时连接到A,B和C. 我正在使用docker-compose文件+ docker stack deploy,每个服务都有一个名称作为接口的主机。 一切都开始成功,工作正常。 经过一段时间(20分钟,1小时,..)我无法提出接口请求。 接口收到我的请求,但应用程序与服务A,B,C或全部服务失去连接。 如果我重新启动接口,它可以重新连接到服务A,B,C。

我首先认为这是应用程序的问题,所以我在每个服务(接口,A,B,C)上公开了2个新的端口,并连接到分析器和debugging器。 应用程序正常运行,没有泄漏,没有阻塞的线程,正常工作和等待连接。 debugging器告诉我,当我向接口和接口请求尝试请求服务A时,抛出了由同位体exception重置的连接。

在debugging过程中,我发现有趣的东西。 当服务启动时,我将debugging器附加到接口上,一段时间后debugging器也断开连接。 +我无法重新连接,直到我向容器 – >应用程序发出请求。 问题 – 握手失败。

另一个有趣的东西,我发现是我无法要求任何接口。 所以我用wireshark来看看发生了什么事情:SYN – ACK很好。 然后应用程序发布一些数据和接口用FIN,ACK进行响应。 我认为这也发生在接口试图请求服务A和它FIN连接。 接口的代码库,A,B和C对于netty服务器是一样的。

最后,我不认为这是一个应用程序问题。 为什么? 我试图部署容器不作为服务。 我分别运行每个容器,发布每个端口的服务端点和设置为localhost。 (不覆盖networking)。 它正在工作。 容器运行没有问题。 +在开始时我没有说过,当java应用程序(接口,A,B,C)作为独立应用程序运行时没有问题,而不是在docker中运行。

你能帮我解决这个问题吗? 为什么docker在覆盖networking的情况下closures套接字?

我正在使用最新的docker工人。 我也用得比较老。

最后,我能解决这个问题。

发生了什么,又一次。 接口打开与A,B,C的永久TCP连接。 当您尝试运行这些服务A,B,C作为独立的Java应用程序时,一切正常。 当我们将它们docker化,并在群集中运行时,只需要几分钟的时间。 奇怪的是,当你向客户端发出一个请求时,Interface和另一个服务之间的连接中断了。

许多许多不成功的testing和debugging每个容器后,我试图分别运行每个docker容器,映射的端口和端点我指定本地主机。 (每个容器暴露的端口和接口连接到本地主机)有趣的事情发生,它正在工作。 当你像这样运行容器时,使用不同的容器networking驱动程序。 桥一个。 如果在群集中运行它,则使用覆盖networking驱动程序。

所以它必须是dockernetworking的东西,而不是应用程序本身。 下一步是几分钟之后,每个容器的tcpdump,当它应该停止工作。 它很有意思。

  • 客户端 – >接口(确定,请求接受)
  • 接口 – >(转发请求,因为它属于A)A
    • 界面 – > A [POST]
    • A – >接口[RESET]

A几分钟后重新打开TCP通信,没有通信。 为什么?

Docker使用IP虚拟服务器,IPVS维护自己的连接表。 IPVS表中CLOSE_WAIT连接的默认超时值是60秒。 因此,当服务器在60秒后发送一些东西时,IPVS连接不再可用,并且该数据包对于新的TCP会话看起来无效并且获得RST。 在客户端,连接永远保持在FIN_WAIT2状态,因为应用程序仍然打开套接字; 内核的fin_wait计时器只为孤立的TCP套接字启动。

这是我读到的,如何理解它。 我不确定我对问题的解释是否正确,但是基于这些假设,我在接口和A,B,C服务之间实现了乒乓,以防在<60秒内没有通信。 而且,它正在工作。