如何使用netshoot和network_mode捕获Docker Swarm容器的网络流量?



在过去,我们已经成功地使用nicolaka/netshoot来捕获使用docker-compose运行的Docker容器的网络流量:

$ cat docker-compose.yml
version: "3.6"
services:
tcpdump:
image: nicolaka/netshoot
depends_on:
- nginx
command: tcpdump -i any -w /data/nginx.pcap
network_mode: service:nginx
volumes:
- $PWD/data:/data
nginx:
image: nginx:alpine
ports:
- 80:80
$ docker-compose up
WARNING: The Docker Engine you're using is running in swarm mode.
Compose does not use swarm mode to deploy services to multiple nodes in a swarm. All containers will be scheduled on the current node.
To deploy your application across the swarm, use `docker stack deploy`.
Creating network "netshoot_default" with the default driver
Creating netshoot_nginx_1 ... done
Creating netshoot_tcpdump_1 ... done
$ curl -s -o /dev/null http://localhost
$ docker-compose down
Stopping netshoot_tcpdump_1 ... done
Stopping netshoot_nginx_1   ... done
Removing netshoot_tcpdump_1 ... done
Removing netshoot_nginx_1   ... done
Removing network netshoot_default
$ tshark -2 -r data/nginx.pcap http
13   4.760638   172.25.0.1 → 172.25.0.2   HTTP 145 GET / HTTP/1.1
17   4.760866   172.25.0.2 → 172.25.0.1   HTTP 684 HTTP/1.1 200 OK  (text/html)
$

不幸的是,如果容器以docker stack create启动,这似乎不起作用,因为不支持network_mode:

$ docker stack deploy -c docker-compose.yml netshoot
Ignoring unsupported options: network_mode
Creating network netshoot_default
Creating service netshoot_tcpdump
Creating service netshoot_nginx
$ curl -s -o /dev/null http://localhost
$ docker stack rm netshoot
Removing service netshoot_nginx
Removing service netshoot_tcpdump
Removing network netshoot_default
$ tshark -2 -r data/nginx.pcap http
$ tshark -2 -r data/nginx.pcap tcp
6   4.221820   172.18.0.1 → 172.18.0.2   TCP 80 63798 → 80 [SYN] Seq=0 Win=65495 Len=0 MSS=65495 SACK_PERM=1 TSval=191764735 TSecr=0 WS=128
$

如何在docker-compose中配置netshoot容器?

如果它们是通过docker stack create启动的,也可以共享其他容器的网络接口。

from there: https://forums.docker.com/t/how-to-tcpdump-inter-service-traffic/23463/4

集群中的覆盖网络流量不通过docker0或docker_gwbridge。有两种选择:选项1:进入容器并执行tcpdump:Nicolaka/netshoot是所有网络调试工具的容器。

docker run -ti --net container: <container name/id> nicolaka/netshoot
tcpdump -i <eth0>

选项2:进入覆盖网络的网络命名空间,执行tcpdump:首先用docker网络检查找到覆盖网络id启动调试容器挂载网络命名空间:

docker run -it --rm -v /var/run/docker/netns:/var/run/docker/netns --privileged=true nicolaka/netshoot

所有命名空间都列在下面:/var/run/docker/netns

查找与前面命令的overlay networkid匹配的swarm overlay network namespace。然后进入网络命名空间:

nsenter --net=/var/run/docker/netns/ sh
tcpdump -i vxlan0

我不知道这是否适用于您正在尝试做的事情,但您仍然可以附加到服务容器的网络命名空间

假设你已经为你的docker swarm节点设置了无密码ssh,如下所示:docker -H ssh://user@nodeN container ls从一个docker节点检索容器列表,然后:

docker service ps --no-trunc service_of_interest

将返回每个服务任务的ID、Name和Node。选择一个。然后在同一个节点上运行netshoot:

docker -H ssh://user@$NODE run --rm -it --network container:$NAME.$ID nicolaka/netshoot

您可以从Makefile中自动执行此操作。但把它放在一个码头作曲。因为你需要提供太多动态查找的细节,并且需要在特定节点上调用docker,所以Yml无法正常运行。

最新更新