我正在尝试弄清楚如何跟踪来自 Docker 容器的带宽。
通常我使用--uid-owner
as 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