计算 Docker 容器的带宽

计算 Docker 容器的带宽

我正在尝试弄清楚如何跟踪来自 Docker 容器的带宽。

通常我使用--uid-owneras mark 来跟踪给定用户的带宽使用情况。但是,即使我以用户身份运行 Docker 容器内的所有进程也--uid-owner不起作用。--uid-owner我没有使用,而是尝试跟踪来自 Docker 创建的虚拟以太网设备的所有数据包。

然而,这最终也没有任何作用:无论我怎么尝试,都没有捕获到数据包。

出于绝望,我尝试将规则放入所有链中,但也没有结果。

Chain PREROUTING (policy ACCEPT 3041 packets, 7849454 bytes)
num      pkts      bytes target     prot opt in     out     source               destination
1           0        0 MARK       tcp  --  veth5a36 any     anywhere             anywhere             MARK set 0x1

Chain INPUT (policy ACCEPT 273 packets, 23305 bytes)
num      pkts      bytes target     prot opt in     out     source               destination
1           0        0 MARK       tcp  --  veth5a36 any     anywhere             anywhere             MARK set 0x1

Chain FORWARD (policy ACCEPT 2750 packets, 7821109 bytes)
num      pkts      bytes target     prot opt in     out     source               destination
1           0        0 MARK       tcp  --  any    veth5a36  anywhere             anywhere             MARK set 0x1
2           0        0 MARK       tcp  --  veth5a36 any     anywhere             anywhere             MARK set 0x1
3           0        0            all  --  veth5a36 eth0    anywhere             anywhere             mark match 0x1

Chain OUTPUT (policy ACCEPT 293 packets, 80020 bytes)
num      pkts      bytes target     prot opt in     out     source               destination
1           0        0 MARK       tcp  --  any    veth5a36  anywhere             anywhere             MARK set 0x1

Chain POSTROUTING (policy ACCEPT 3043 packets, 7901129 bytes)
num      pkts      bytes target     prot opt in     out     source               destination
1           0        0 MARK       tcp  --  any    veth5a36  anywhere             anywhere             MARK set 0x1

有人能告诉我如何成功标记来自 docker 容器的软件包吗?最好使用,--uid-owner但我现在什么都愿意做 :)

答案1

问题与命名空间有关。Docker 使用它们来隔离资源,这也意味着它们不计入主机的总数。

当您iptables在主机上运行时,您基本上只会查看主机的命名空间,而您感兴趣的数据包会被记录到容器的命名空间中。要解决这个问题,您可以ip netns仍然在主机上运行 iptables,但在容器的网络命名空间中运行。

首先,ip netns有一个有点违反直觉的界面。为了附加到现有进程(在本例中是您的容器)的命名空间,您必须创建一个指向/var/run/netns/该进程命名空间的链接:

# ln -sf /proc/`docker inspect -f '{{ .State.Pid }}' YOUR_CONTAINER`/ns/net /var/run/netns/SOME_NAME

(你可能必须mkdir /var/run/netns

现在您可以在容器的命名空间中自由运行 iptables:

# ip netns exec SOME_NAME iptables -L -nv

请注意,这将输出容器内的 iptables 规则集,该规则集可能为空。

如果您当前仅使用 --uid-owner 来拥有每个用户计数器,那么您甚至不再需要它了,因为在这种情况下链计数器仅适用于容器,然后就足够了。

最后,您就可以进行清理了/var/run/netns

每个用户有多个容器

如果每个用户有多个容器并且想要将它们统计在一起,则可以使用 启动容器--net=container:OTHER_CONTAINER_FROM_USER,以便合并它们的命名空间。

这样做的缺点是合并了网络堆栈的所有方面,包括开放端口,因此同一用户的两个容器不能监听同一个端口。

如果这是一个禁止性限制,您可以单独统计容器,然后根据 uid 进行分组。

您可以找到有关此问题的更多信息这里

答案2

虽然不完全符合您的要求,但我认为它能完成工作。

引自Docker 博客

接口级计数器

由于每个容器都有一个虚拟以太网接口,您可能希望直接检查该接口的 TX 和 RX 计数器。

[...]

但目前,最好的方法是从容器内部检查指标。我不是在谈论在容器中运行特殊代理或类似的东西。我们将从主机环境运行可执行文件,但在容器的网络命名空间内运行。

该命令的具体格式为:

ip netns exec <nsname> <command...>

例如:

ip netns exec mycontainer netstat -i

相关内容