如何在 Kubernetes 下轻松抓取应用网络包

#1. 宿主机上捕获

我们知道应用其实是运行在 Pod 内的 Container 里的,所以只要定位到 Container 被调度到了哪个 Node 上,在相应的 Node 里,对容器进行抓包即可。

0) 先决条件

需要有宿主机的访问权限

1) 定位 Pod 的 containerID 以及它所运行的宿主机 IP

在 Kubernetes 集群内执行下面这个指令,并从返回的结果中拿到两个信息

  1. 宿主机 IP = 172.18.0.xxx
  2. container ID = 78e91175699f.....
# 注: 需要替换 namespace 和 pod name
➜ kubectl get pod \
-n ${NAMESPACE}${POD_NAME} \
-o json|jq '.status|{hostIP: .hostIP, container: [.containerStatuses[]|{name: .name, containerID: .containerID}]}'
{
"hostIP": "172.18.0.xxx",
"container": [
{
"name": "linkerd-proxy",
"containerID": "docker://78e91175699f8cc0a3b0ff87da97407c19c7a86706a5b74e2d86f4428a4de75a"
},
{
"name": "nginx",
"containerID": "docker://7a6f7eabc2d5112437d30ee8ec1aa7ef963e97c3d09c3bc63613a70d106d7d01"
}
]
}

2) 查找网络接口索引

通过 ssh 登陆到 Pod 所在的宿主机上,然后在容器内执行 cat /sys/class/net/eth0/iflink,查找容器中的网卡与宿主机的 veth 网卡之间的对应关系

# 注: 需要替换 container id
docker exec -it ${CONTAINER_ID} /bin/bash -c 'cat /sys/class/net/eth0/iflink'
10227

3) 查找网络接口信息

在宿主机上做 ip link 操作

ip link |grep 10227
10227: calicf227ed888a@if4: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1440 qdisc noqueue state UP mode DEFAULT group default

4) 在宿主机上抓包

最后,我们通过 tcpdump 指令,将报文保存到文件中

tcpdump -i calicf227ed888a@if4 -w /root/tcpdump.pcap 

#2. 在 Pod 内抓包

0) 先决条件

  1. 目标 Pod 内的容器里必须要有 tcpdump 工具
  2. 本地安装 wireshark

1) 执行以下命令对目标 Pod 抓包

# 注: -c ${CONTAINER_NAME} 是可选择的。如果 Pod 中仅包含一个容器,就可以忽略它
kubectl exec${POD_NAME} -c ${CONTAINER_NAME} -- tcpdump -i eth0 -w - | wireshark -k -i -

#3. 通过 ephemeral containers 抓包

值得一提的是 Kubernetes 在 v1.16 [Alpha] 开始支持 Ephemeral Containers[2],它正好可以解决上面提的 2 个痛点,临时容器对于排除交互式故障非常有用,Kubernetes 在 v1.23 [beta] 已经默认开启该功能了。

比如我使用 nicolaka/netshoot[3] 镜像用来调试,用法如下

# 注: 需要替换 pod name 和 container name
kubectl debug -i ${POD_NAME} \
--image=nicolaka/netshoot \
--target=${CONTAINER_NAME} -- tcpdump -i eth0 -w - | wireshark -k -i -

#4. 通过 Ksniff 抓包

ksniff 是一个 kubectl 的插件,它利用 tcpdump 和 Wireshark 对 Kubernetes 集群中的任何 Pod 启动远程抓包。

0) 先决条件

安装 Krew
(
set -x; cd"$(mktemp -d)" &&
curl -fsSLO "https://github.com/kubernetes-sigs/krew/releases/latest/download/krew.tar.gz" &&
tar zxvf krew.tar.gz &&
KREW=./krew-"$(uname | tr '[:upper:]' '[:lower:]')_$(uname -m | sed -e 's/x86_64/amd64/' -e 's/arm.*$/arm/')" &&
"$KREW" install krew
)
export PATH="${KREW_ROOT:-$HOME/.krew}/bin:$PATH"
安装 sniff 插件

一旦安装完 Krew 后,就可以通过以下指令完成 sniff 的安装

kubectl krew install sniff

1) 执行 kubectl sniff 命令抓包

# 注:需要替换 pod name 和 namespace
kubectl sniff ${POD_NAME} -n ${NAMESPACE}

执行 sniff 命令后,本地会自动启动 Wireshark 进行抓包,如下图

如何在 Kubernetes 下轻松抓取应用网络包

以下是 sniff 运行的日志,我只提取了日志的关键部分

➜ kubectl sniff httpbin -n default

time="2022-02-20T19:56:13+08:00" level=info msg="using tcpdump path at: '/Users/linqiong/.krew/store/sniff/v1.6.1/static-tcpdump'"
time="2022-02-20T19:56:13+08:00" level=info msg="selected container: 'httpbin'"
time="2022-02-20T19:56:13+08:00" level=info msg="uploading file: '/Users/linqiong/.krew/store/sniff/v1.6.1/static-tcpdump' to '/tmp/static-tcpdump' on container: 'httpbin'"
....
time="2022-02-20T19:56:14+08:00" level=info msg="tcpdump uploaded successfully"
time="2022-02-20T19:56:14+08:00" level=info msg="spawning wireshark!"
time="2022-02-20T19:56:14+08:00" level=info msg="start sniffing on remote container"
time="2022-02-20T19:56:14+08:00" level=info msg="executing command: '[/tmp/static-tcpdump -i any -U -w - ]' on container: 'httpbin', pod: 'httpbin', namespace: 'default'"

从运行的日志来看,sniff 是将本地的 static-tcpdump 文件上传到 Pod 的指定容器的 /tmp 目录下,然后在容器内,通过运行以下命令来达到抓包的目的

/tmp/static-tcpdump -i any -U -w -

另外需要说明的是,如果你是在服务器上执行,且服务器并没有安装 wireshark,你可以将报文输出到文件中,然后用本地的 wireshark 来解析报文。

kubectl sniff httpbin -n default -o httpbin.pcap

文章来源:https://www.cnaaa.net,转载请注明出处:https://www.cnaaa.net/archives/9551

(0)
郭靖的头像郭靖
上一篇 2023年8月16日 下午6:10
下一篇 2023年8月17日 下午4:33

相关推荐

  • iptables与firewalld的区别

    iptables与firewalld的区别 firewalld可以动态修改单条规则,动态管理规则集,允许更新规则而不破坏现有会话和连接。而iptables,在修改了规则后必须得全部刷新才可以生效; firewalld使用区域和服务而不是链式规则; firewalld默认是拒绝的,需要设置以后才能放行。而iptables默认是允许的,需要拒绝的才去限制; fi…

    2022年8月9日
    1.3K00
  • 内网穿透—frp

    什么是frp内网穿透 frp 是一个开源项目, 采用 C/S 模式,将服务端部署在具有公网 IP 的机器上,客户端部署在内网或防火墙内的机器上,通过访问暴露在服务器上的端口,反向代理到处于内网的服务。 在此基础上,frp 支持 TCP, UDP, HTTP, HTTPS 等多种协议,提供了加密、压缩,身份认证,代理限速,负载均衡等众多能力。 为什么使用frp…

    2022年6月8日
    1.8K00
  • 将 COS 作为本地磁盘挂载到 Windows 服务器

    下载与安装 本案例实践使用到以下三种软件,您可选择安装适用于自己所使用系统的软件版本: 说明: Github 下载速度可能比较慢甚至打不开,可自行在其他官方渠道进行下载。 配置 Rclone 注意: 以下配置步骤以 rclone-v1.60.1-windows-amd64 版本为例,其他版本的配置过程可能存在一定差异,请注意相应调整。 修改配置文件 以上步骤…

    2023年3月8日
    1.2K00
  • 配置ospf路由实现内网访问外网

    1、网络拓扑图 2、核心命令 [r1-ospf-100]default-route-advertise always  说明:给ospf 进程中添加一条缺省路由 3、具体配置如下

    2024年6月20日
    80900
  • 局域网IP地址冲突、环路的罪魁祸首是什么?

    中午好,我的网工朋友。 这个时代,网络已经贯穿了人们的生活,对企业而言,办公信息化更是离不开网络支持。 为了提高安全管理和信息化水平,很多企业都建立了完善的办公信息系统,但一些企业在网络建设方面还是会有各种问题存在。 比如说,由于缺乏全面规划,或在选择网络产品时考虑不够周全,导致网络建设未能达到预期效果,随后出现了许多应用问题。 这些问题可能包括网络漏洞,导…

    2024年1月9日
    90300

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

在线咨询: QQ交谈

邮件:712342017@qq.com

工作时间:周一至周五,8:30-17:30,节假日休息

关注微信