首页 > 解决方案 > 为什么启动 docker 容器时有这么多 NETLINK rtm_newlink 消息

问题描述

我正在开发一个数据包嗅探器应用程序并对其进行设置,以便每个接口有一个捕获线程(而不是在“全部”上捕获一个线程)。它工作正常,但代码需要监听接口列表的更改,以便它可以管理捕获线程。

我编写了一个小函数,使用 netlink api 在 nl_groups 字段中使用 RTMGRP_LINK 并专门针对 RTM_DELLINK 和 RTM_NEWLINK 消息类型执行我想要的操作。它按预期工作,但我并不真正理解 docker 容器根据从内核接收的消息启动时的逻辑。

例如,运行docker run -it centos:7 /bin/bash会创建以下消息流:

RTM_NEWLINK NAME: vethaec0b80 MAC: a2:a1:2c:48:72:f4
RTM_NEWLINK NAME: vethb4ca0db MAC: fe:e8:79:7a:ce:d9
RTM_NEWLINK NAME: vethb4ca0db MAC: fe:e8:79:7a:ce:d9
RTM_NEWLINK NAME: vethb4ca0db MAC: fe:e8:79:7a:ce:d9
RTM_NEWLINK NAME: docker0 MAC: 02:42:0d:8f:a2:f9
RTM_NEWLINK NAME: vethb4ca0db MAC: fe:e8:79:7a:ce:d9
RTM_NEWLINK NAME: vethb4ca0db MAC: fe:e8:79:7a:ce:d9
RTM_NEWLINK NAME: vethb4ca0db MAC: fe:e8:79:7a:ce:d9
RTM_NEWLINK NAME: vethb4ca0db MAC: fe:e8:79:7a:ce:d9
RTM_NEWLINK NAME: vethb4ca0db MAC: fe:e8:79:7a:ce:d9
RTM_NEWLINK NAME: vethb4ca0db MAC: fe:e8:79:7a:ce:d9
RTM_NEWLINK NAME: vethb4ca0db MAC: fe:e8:79:7a:ce:d9
RTM_NEWLINK NAME: vethb4ca0db MAC: fe:e8:79:7a:ce:d9
RTM_NEWLINK NAME: docker0 MAC: 02:42:0d:8f:a2:f9
RTM_DELLINK NAME: vethaec0b80 MAC: a2:a1:2c:48:72:f4
RTM_NEWLINK NAME: vethb4ca0db MAC: fe:e8:79:7a:ce:d9
RTM_NEWLINK NAME: vethb4ca0db MAC: fe:e8:79:7a:ce:d9
RTM_NEWLINK NAME: vethb4ca0db MAC: fe:e8:79:7a:ce:d9
RTM_NEWLINK NAME: vethb4ca0db MAC: fe:e8:79:7a:ce:d9
RTM_NEWLINK NAME: docker0 MAC: 02:42:0d:8f:a2:f9

并退出容器生成:

RTM_NEWLINK NAME: vethaec0b80 MAC: 02:42:ac:11:00:02
RTM_NEWLINK NAME: vethb4ca0db MAC: fe:e8:79:7a:ce:d9
RTM_NEWLINK NAME: vethb4ca0db MAC: fe:e8:79:7a:ce:d9
RTM_NEWLINK NAME: vethb4ca0db MAC: fe:e8:79:7a:ce:d9
RTM_NEWLINK NAME: vethb4ca0db MAC: fe:e8:79:7a:ce:d9
RTM_NEWLINK NAME: vethb4ca0db MAC: fe:e8:79:7a:ce:d9
RTM_NEWLINK NAME: vethb4ca0db MAC: fe:e8:79:7a:ce:d9
RTM_DELLINK NAME: vethaec0b80 MAC: 02:42:ac:11:00:02
RTM_NEWLINK NAME: vethb4ca0db MAC: fe:e8:79:7a:ce:d9
RTM_DELLINK NAME: vethb4ca0db MAC: fe:e8:79:7a:ce:d9
RTM_NEWLINK NAME: docker0 MAC: 02:42:0d:8f:a2:f9
RTM_DELLINK NAME: vethb4ca0db MAC: fe:e8:79:7a:ce:d9
RTM_NEWLINK NAME: docker0 MAC: 02:42:0d:8f:a2:f9

正如您在启动容器时看到的那样,收到了 2 个虚拟接口(其中一个被破坏)和已经启动并运行的 docker 网桥的 RTM_NEWLINK 消息。终止容器也有类似情况;创建了 2 个虚拟接口(在 RTM_NEWLINK 再次调用它们后都被销毁)。

问题

1)为什么在启动容器时创建了2个虚拟接口,只保留了一个?

2) 为什么 RTM_NEWLINK 消息会发送这么多次?

3)在终止容器时,为什么它在发送RTM_DELLINK消息之前发送了这么多RTM_NEWLINK消息?

标签: cdockernetworkingkernelnetlink

解决方案


1)为什么在启动容器时创建了2个虚拟接口,只保留了一个?

一个猜测:Docker 创建了一对连接的接口,然后它在容器中移动一个,这是一个单独的网络命名空间。由于您正在查看默认命名空间,因此您会看到它消失了。如果您在容器的命名空间中,您会看到它出现。

2) 为什么 RTM_NEWLINK 消息会发送这么多次?

3)在终止容器时,为什么它在发送RTM_DELLINK消息之前发送了这么多RTM_NEWLINK消息?

RTM_NEWLINK 不仅在创建接口时发送。当接口被修改时也会发送。


推荐阅读