问小白 wenxiaobai
资讯
历史
科技
环境与自然
成长
游戏
财经
文学与艺术
美食
健康
家居
文化
情感
汽车
三农
军事
旅行
运动
教育
生活
星座命理

tcpdump抓包docker容器之间网络内容

创作时间:
作者:
@小白创作中心

tcpdump抓包docker容器之间网络内容

引用
CSDN
1.
https://blog.csdn.net/weixin_39313293/article/details/137988224

tcpdump抓包docker容器之间网络内容

前言

客户生产环境的客户端上传小文件是可以正常上传的,但在上传大文件到服务器时经常发生卡慢和超时问题,导致无法上传大文件。

为了分析这个问题,我和同事捋了一下服务端架构,架构如下:

Docker内部有容器A和容器B两个服务,容器B的端口12000映射到了宿主机上的端口12000,外部客户端可以正常访问。服务A的端口没有做映射,只允许Docker内部的容器互相访问。

问题分析

客户端到服务器能正常上传小文件,说明网络是正常的。企业内部宽理论上也是够的,因此可以排除前面两个网络存在问题的可能性。剩下的可能性在于服务器内部容器B到容器A两个微服务之间的网络问题。

方案设计

现在要用tcpdump对容器A和容器B的网络进行抓包,该如何做到呐?

第一个方案

从宿主机监听容器A的端口2100,理论上行不通,因为端口没有映射。

第二个方案

在容器内部搭一个tcpdump容器,容器内部网络互通,端口2100可以被tcpdump容器访问,理论上可行,但实际验证下来没有抓到包。因为tcpdump容器本身可以理解为一个完整的操作系统,在里面开启监听,监听到的网卡只是tcpdump容器内部的虚拟网卡,而不是容器A和容器B通信的虚拟网卡。

第三个方案

参考了网上的文章,使用nsenter命令工具,借助这个工具,我们可以进入Linux系统的不同命名空间中并执行命令,docker中运行的容器本身就是一种被隔离的进程。

要实现抓包大致逻辑是:

  1. 在宿主机安装tcpdump工具;
  2. 使用docker命令找到Service A容器对应的宿主机的pid;
  3. 借助nsenter命令,使得tcpdump能够监听到流经Service A容器内部虚拟网卡的流量。

方案验证

安装tcpdump

网上下载tcpdump包,在宿主机安装tcpdump。

tcpdump依赖于 libpcap,因此需要先安装 libpcap。

解压libpcap-1.10.3.tar.gz包,并编译安装。


tar -zxvf libpcap-1.10.3.tar.gz  
cd libpcap-1.10.3  
./configure  
make  
make install  

解压tcpdump并编译安装


tar -zxvf tcpdump-4.99.3.tar.gz  
cd tcpdump-4.99.3  
./configure  
make  
make install  

映射关系查找

用下面命令查找要抓包的docker容器的容器ID,这里查找Service A的容器ID


docker ps | grep 容器名  

得到Service A容器ID后,执行下面这条命令,找到容器在宿主机上对应的PID


docker inspect --format "{{.State.Pid}}" 容器ID  

下图是容器ID(f0541503c0e1)对应的宿主机上的PID(31891)

网络内容抓包

下面命令,PID替换为上一步找到的PID,port 是Service A服务的端口,host 后面是nginx容器的IP,这个IP需要进入容器内部使用命令 ip addr 查看,默认是网卡eth0对应的IP。


nsenter -n -t PID tcpdump -i eth0 dst port 端口 and src host 容器内部IP  
  • nsenter:是一个用于进入指定命名空间的工具。在 Linux 系统中,命名空间用于隔离资源,如进程、网络、挂载点等。
  • -n:表示进入网络命名空间。
  • -t PID:表示目标进程的 PID(进程ID)。这个 PID 通常是一个容器进程的 ID,所以该命令的意图是进入容器的网络命名空间。
  • -i eth0: 指定要捕获流量的网络接口为eth0
  • dst port:表示要监听的目标端口
  • src host:表示要监听的源地址IP

如果要输出抓包内容到文件,可以在上面命令后面追加参数-w /xxx/network.pcap,表示把抓包内容输出到宿主机/xxx路径下的network.pcap文件中,文件名可以自定义。


nsenter -n -t PID tcpdump -i eth0 dst port 2048 and src host 容器内部ip -w /xxx/network.cap  
  • -w:这是一个tcpdump的选项,用于指定将捕获的数据包写入文件的路径

修改完上面这条命令为对应的服务参数后,在宿主机上执行,开始抓包从nginx服务到serviceA的网络。

上传一个273byte(字节)的文件,下面这个是抓到的包内容


16:05:21.396649 IP 10.0.2.22.40270 > xxx-server.dls-monitor: Flags [S], seq 2702839680, win 28200, options [mss 1410,sackOK,TS val 475563759 ecr 0,nop,wscale 7], length 0  
16:05:21.396682 IP 10.0.2.22.40270 > xxx-server.dls-monitor: Flags [.], ack 3865746325, win 221, options [nop,nop,TS val 475563759 ecr 475563759], length 0  
16:05:21.396792 IP 10.0.2.22.40270 > xxx-server.dls-monitor: Flags [P.], seq 0:563, ack 1, win 221, options [nop,nop,TS val 475563759 ecr 475563759], length 563  
16:05:21.396829 IP 10.0.2.22.40270 > xxx-server.dls-monitor: Flags [P.], seq 563:2021, ack 1, win 221, options [nop,nop,TS val 475563759 ecr 475563759], length 1458  
16:05:21.476387 IP 10.0.2.22.40270 > xxx-server.dls-monitor: Flags [.], ack 165, win 229, options [nop,nop,TS val 475563839 ecr 475563839], length 0  
16:05:21.476548 IP 10.0.2.22.40270 > xxx-server.dls-monitor: Flags [F.], seq 2021, ack 165, win 229, options [nop,nop,TS val 475563839 ecr 475563839], length 0  
16:05:21.476822 IP 10.0.2.22.40270 > xxx-server.dls-monitor: Flags [.], ack 166, win 229, options [nop,nop,TS val 475563839 ecr 475563839], length 0  

分析抓包内容

将上面抓到的网络内容交由AI分析,AI对这段信息的分析如下:

  1. 第一行数据包:
  • 时间戳:16:05:21.396649
  • IP地址:10.0.2.22.40270 > xxx-server.dls-monitor
  • Flags:[S],表示这是一个SYN(同步)报文
  • seq:2702839680,表示序列号为2702839680
  • win:28200,表示窗口大小为28200
  • options:[mss 1410,sackOK,TS val 475563759 ecr 0,nop,wscale 7],表示使用了最大报文段长度(MSS)为1410,支持选择性确认(SACK),时间戳值为475563759,扩展最大报文段长度(WSCALE)为7
  • length:0,表示该报文没有负载数据
  1. 第二行数据包:
  • 时间戳:16:05:21.396682
  • IP地址:10.0.2.22.40270 > xxx-server.dls-monitor
  • Flags:[.],表示这是一个ACK(确认)报文
  • ack:3865746325,表示确认号为3865746325
  • win:221,表示窗口大小为221
  • options:[nop,nop,TS val 475563759 ecr 475563759],表示时间戳值为475563759,扩展最大报文段长度(ECR)为475563759
  • length:0,表示该报文没有负载数据
  1. 第三行数据包:
  • 时间戳:16:05:21.396792
  • IP地址:10.0.2.22.40270 > xxx-server.dls-monitor
  • Flags:[P.],表示这是一个PSH(推送)和ACK(确认)报文
  • seq:0:563,表示序列号范围为0到563
  • ack:1,表示确认号为1
  • win:221,表示窗口大小为221
  • options:[nop,nop,TS val 475563759 ecr 475563759],表示时间戳值为475563759,扩展最大报文段长度(ECR)为475563759
  • length:563,表示该报文的负载数据长度为563字节
  1. 第四行数据包:
  • 时间戳:16:05:21.396829
  • IP地址:10.0.2.22.40270 > xxx-server.dls-monitor
  • Flags:[P.],表示这是一个PSH(推送)和ACK(确认)报文
  • seq:563:2021,表示序列号范围为563到2021
  • ack:1,表示确认号为1
  • win:221,表示窗口大小为221
  • options:[nop,nop,TS val 475563759 ecr 475563759],表示时间戳值为475563759,扩展最大报文段长度(ECR)为475563759
  • length:1458,表示该报文的负载数据长度为1458字节
  1. 第五行数据包:
  • 时间戳:16:05:21.476387
  • IP地址:10.0.2.22.40270 > xxx-server.dls-monitor
  • Flags:[.],表示这是一个ACK(确认)报文
  • ack:165,表示确认号为165
  • win:229,表示窗口大小为229
  • options:[nop,nop,TS val 475563839 ecr 475563839],表示时间戳值为475563839,扩展最大报文段长度(ECR)为475563839
  • length:0,表示该报文没有负载数据
  1. 第六行数据包:
  • 时间戳:16:05:21.476548
  • IP地址:10.0.2.22.40270 > xxx-server.dls-monitor
  • Flags:[F.],表示这是一个FIN(结束)和ACK(确认)报文
  • seq:2021,表示序列号为2021
  • ack:165,表示确认号为165
  • win:229,表示窗口大小为229
  • options:[nop,nop,TS val 475563839 ecr 475563839],表示时间戳值为475563839,扩展最大报文段长度(ECR)为475563839
  • length:0,表示该报文没有负载数据
  1. 第七行数据包:
  • 时间戳:16:05:21.476822
  • IP地址:10.0.2.22.40270 > xxx-server.dls-monitor
  • Flags:[.],表示这是一个ACK(确认)报文
  • ack:166,表示确认号为166
  • win:229,表示窗口大小为229
  • options:[nop,nop,TS val 475563839 ecr 475563839],表示时间戳值为475563839,扩展最大报文段长度(ECR)为475563839
  • length:0,表示该报文没有负载数据

上面这段分析的内容是关于网络数据包的抓取和分析。根据tcpdump工具抓取的数据包信息,可以得出以下结论:

  1. 第一行数据包是一个SYN报文,表示建立连接的请求。
  2. 第二行数据包是一个ACK报文,表示确认连接的建立。
  3. 第三行和第四行数据包都是PSH和ACK报文,表示传输数据的请求和确认。
  4. 第五行数据包是一个ACK报文,表示确认数据的接收。
  5. 第六行数据包是一个FIN和ACK报文,表示结束连接的请求和确认。
  6. 第七行数据包是一个ACK报文,表示确认连接的关闭。

具体的网络数据包分析可使用wireshark。

备注说明:

  1. 报文分析和报文内容总结由AI讯飞星火生成。
  2. 上面的操作是在测试环境验证抓包的可行性,不是实际生产环境大文件上传慢时抓的包。

参考

计算机网络抓包工具——tcpdump详解-CSDN博客
docker(k8s)容器内tcpdump抓包 - 简书

© 2023 北京元石科技有限公司 ◎ 京公网安备 11010802042949号