作家
登录

Docker容器网络下UDP协议的一个问题

作者: 来源: 2017-08-23 09:49:41 阅读 我要评论

【51CTO晃荡】8.26 带你与清华大年夜学、搜狗、京东大年夜咖们一路商量基于算法的IT运维实践


那么问题的原因也可以分为两个部分:

  1. 为什么竽暌功答报文源地址是 缺点的 ?
  2. 既然 UDP 是无状况的,内核怎么断定源地址不精确呢?

我们有个应用是 UDP 协定的,安排上去发明无法工作,然则换成 TCP 协定是可以的(应用同时支撑 UDP、TCP 协定,切换成 TCP 模式发明一切正常)。固然换成 TCP 能解决问题,然则我们照样想知道到底 UDP 协定在收集模式下为什么会出现这个问题,以防止后面其他 UDP 应用会有异常。

这个问题抽象出来是如许的:如不雅有 UDP 办事运行在主机上(或者运行在收集模型为 Host 的容器里),并且监听在 0.0.0.0 地址(也就是所有的 ip 地址),大年夜运行在 docker bridge 收集的容器运行客户端拜访办事,两者通信有问题。

留意以上的的限制前提,经由过程测试,我们发明下来几种情况都是正常的:

  • 应用 TCP 协定没有这个问题,这个已经说过了
  • 如不雅 UDP 办事器监听在 eth0 IP 地址上也不会出现这个问题
  • 并不是所有的应用都有这个问题,我们的 DNS(dnsmasq + kubeDNS) 也是同样的安排方法,然则功能都正常

这个问题在 docker 上也有 issue 记录:https://github.com/moby/moby/issues/15127,然则今朝并没有合理的解决筹划。

问题重现

这个问题很轻易重现,我的实验是在 ubuntu16.04 下用 netcat 敕令完成的,其他体系应当类似。在主机上经由过程 nc 监听 56789 端口,然后在容器里应用 nc 发数据。第一个报文是能发送出去的,然则今后的报文固然在收集上能看到,然则对方无法接收。

在主机上运行 nc UDP 办事器( -u 表示 UDP 协定, -l 表示监听的端口)

  1. $ nc -ul 56789 

然后启动一个容器,运行客户端:

  1. $ docker run -it apline sh 
  2. / # nc -u 172.16.13.13 56789 

nc 的通信是两边的,不管对方输入什么字符,回车后对方就能急速收到。然则在这个模式下,客户端第一次输入对方可以或许收到,后续的报文对方都收不到。

在这个实验中,容器应用的是 docker 的默认收集,容器的 ip 是 172.17.0.3,经由过程 veth pair(图中没有显示)连接到虚拟网桥 docker0(ip 地址为 172.17.0.1),主机本身的收集为 eth0,其 ip 地址为 172.16.13.13。

  1. 172.17.0.3 
  2. +----------+ 
  3. |   eth0   | 
  4. +----+-----+ 
  5.      | 
  6.      | 
  7.      | 
  8.      | 
  9. +----+-----+          +----------+ 
  10. | docker0  |          |  eth0    | 
  11. +----------+          +----------+ 
  12. 172.17.0.1            172.16.13.13 

tcpdump 抓包

碰到这种疑难杂症,第一个想到的抓包,我们须要在 docker0 上抓包,因为这是报文必经由的处所。经由过程过滤容器的 ip 地址,很容器找到感兴趣的报文:

  1. $ tcpdump -i docker0 -nn host 172.17.0.3 

为了模仿多半应用一问一答的通信方法,我们一共发送三个报文,并用 tcpdump 抓取 docker0 接口上的报文:

  1. 客户端先向办事器端发送 hello 字符串
  2. 办事器端答复 world
  3. 客户端持续发送 hi 消息

如不雅 ipi_spec_dst 和 ipi_ifindex 不为空,它们都能作为源地址选择的根据,而不是让内核经由过程路由决定。

抓包的结不雅如下,可以发明第一个报文发送出去没有任何问题(因为 UDP 是没有 ACK 报文的,所以客户端无法知道对方有没有收到,这里说的没有问题是值没有对应的 ICMP 报文),然则第二个报文大年夜办事端发送的报文,对方会返回一个 ICMP 告诉端口 38908 弗成达;第三个报文大年夜客户端发送的报文也是如斯。今后的报文情况类似,两边再也无法进行通信了。

  1. 11:20:43.973286 IP 172.17.0.3.38908 > 172.16.13.13.56789: UDP, length 6 
  2. 11:20:50.102018 IP 172.17.0.1.56789 > 172.17.0.3.38908: UDP, length 6 
  3. 11:20:50.102129 IP 172.17.0.3 > 172.17.0.1: ICMP 172.17.0.3 udp port 38908 unreachable, length 42 
     1/5    1 2 3 4 5 下一页 尾页

      推荐阅读

      如何确定恶意软件是否在自己的电脑中执行过?

    【51CTO晃荡】8.26 带你与清华大年夜学、搜狗、京东大年夜咖们一路商量基于算法的IT运维实践 很不幸,你在本身的电脑里发清楚明了一个恶意的可履行法度榜样!那么问题来了:这个文件到底有>>>详细阅读


    本文标题:Docker容器网络下UDP协议的一个问题

    地址:http://www.17bianji.com/lsqh/36867.html

关键词: 探索发现

乐购科技部分新闻及文章转载自互联网,供读者交流和学习,若有涉及作者版权等问题请及时与我们联系,以便更正、删除或按规定办理。感谢所有提供资讯的网站,欢迎各类媒体与乐购科技进行文章共享合作。

网友点评
自媒体专栏

评论

热度

精彩导读
栏目ID=71的表不存在(操作类型=0)