网络诊断利器:掌握 Kubernetes Pod 抓包技巧

29 篇文章 0 订阅
13 篇文章 0 订阅

转载:网络诊断利器:掌握 Kubernetes Pod 抓包技巧 

背景

有没有对Pod抓包而感到苦恼,下面针对在线上出现问题之后,针对Pod进行抓包

1. 宿主机上捕获

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

2.1 定位Pod ip和containerID

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

# kubectl get pod -n ${NAMESPACE}${POD_NAME} -o json|jq '.status|{hostIP: .hostIP, container: [.containerStatuses[]|{name: .name, containerID: .containerID}]}'

{
  "hostIP": "10.103.236.203",
  "container": [
    {
      "name": "app",
      "containerID": "docker://808605e67373b6dee49162c67745e8cd0f5062978385707c91e42d1c37bfba57"
    }
  ]
}

2.2 查找网络接口索引

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

kubectl exec -it ${PodName} -- /bin/sh -c "cat /sys/class/net/eth0/iflink"

[root@kube-master ~]# kubectl exec -it app-prod-97dfb4bf-h59vq -- /bin/sh -c "cat /sys/class/net/eth0/iflink"
14

2.3 查找网络接口信息

[root@kube-master ~]# ip link |grep 14
14: cali3002ec233ba@if4: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1480 qdisc noqueue state UP mode DEFAULT group default

2.4 在宿主机上抓包

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

2. 在 Pod 内抓包

kubectl exec${POD_NAME}  -- tcpdump -i eth0 -w - | wireshark -k -i -

这种方式的安装tcpdump ,增加了镜像的大小 ,不建议这种方式

2.1 通过nsenter

2.1.1 是什么

nsenter命令是一个可以在指定进程的命令空间下运行指定程序的命令

2.1.2 安装

#下载
wget https://www.kernel.org/pub/linux/utils/util-linux/v2.40/util-linux-2.40.tar.gz

#解压
tar zxvf util-linux-2.40.tar.gz && cd util-linux-2.40

#编译
./configure --without-ncurses && make 

cp nsenter /usr/bin/
  • 或者yum 安装

yum install util-linux

2.1.3 帮助

nsenter --help

选项:
 -a, --all              enter all namespaces
 -t, --target <pid>     要获取名字空间的目标进程
 -m, --mount[=<文件>]   进入 mount 名字空间
 -u, --uts[=<文件>]     进入 UTS 名字空间(主机名等)
 -i, --ipc[=<文件>]     进入 System V IPC 名字空间
 -n, --net[=<文件>]     进入网络名字空间
 -p, --pid[=<文件>]     进入 pid 名字空间
 -C, --cgroup[=<文件>]  进入 cgroup 名字空间
 -U, --user[=<文件>]    进入用户名字空间
 -S, --setuid <uid>     设置进入空间中的 uid
 -G, --setgid <gid>     设置进入名字空间中的 gid
     --preserve-credentials 不干涉 uid 或 gid
 -r, --root[=<目录>]     设置根目录
 -w, --wd[=<dir>]       设置工作目录
 -F, --no-fork          执行 <程序> 前不 fork
 -Z, --follow-context  根据 --target PID 设置 SELinux 环境

 -h, --help             display this help
 -V, --version          display version

2.1.4 调试Pod网络

  • 获取pid

kubectl get pods -A -o wide 
  • 到pod所在node节点上面

[root@kube-node02 ~]# docker inspect 808605e67373 |grep Pid
            "Pid": 7004,
            "PidMode": "",
            "PidsLimit": null,
  • 进入到pod

nsenter -t 7004 -n

2.1.5 抓包

 tcpdump -nnnvv -As 0 -i eth0 port 80 -w demo2.pcap

参数解释

-nnn:
第一个 n 表示不将网络地址转换为名称。这意味着 tcpdump 会显示 IP 地址而不是尝试将它们解析为主机名。
第二个 n 也是同样的作用,但有些版本的 tcpdump 可能不支持重复使用 -n 选项。在这种情况下,第二个 n 可能会被忽略。
第三个 n(如果支持)通常表示不将端口号转换为服务名称,即显示端口号的数字而不是服务名称。

-vv:
第一个 v 表示详细输出。这会提供更多的信息,比如数据包的头部信息。
第二个 v 表示更详细的输出。这会提供比单个 -v 更详细的信息。

-A:表示以 ASCII 格式打印每个数据包的内容,方便阅读文本数据。

-s 0:
-s 选项后跟一个数值,表示从每个捕获的数据包中截取的字节数。0 表示不截取,即捕获每个数据包的全部内容,而不是只捕获前若干字节。

3. ksniff抓包

推荐这个方式

3.1 介绍

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

3.1 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"

3.2 sniff安装


[root@kube-master ~]# kubectl krew install sniff
Updated the local copy of plugin index.
Installing plugin: sniff
W0710 17:54:14.755671   84252 install.go:160] Skipping plugin "sniff", it is already installed

3.3 sniff抓包

  • 本地

# 注:需要替换 pod name 和 namespace ,这个本地会执行wireshark
kubectl sniff ${POD_NAME} -n ${NAMESPACE}
  • 服务器

服务器并没有安装 wireshark,你可以将报文输出到文件中,然后用本地的 wireshark 来解析报文

kubectl sniff ${POD_NAME} -n ${NAMESPACE} -o httpbin.pcap
  • 案例

INFO[0000] using tcpdump path at: '/root/.krew/store/sniff/v1.6.2/static-tcpdump'
INFO[0000] no container specified, taking first container we found in pod.
INFO[0000] selected container: 'app'
INFO[0000] sniffing method: upload static tcpdump
INFO[0000] sniffing on pod: 'app-prod-97dfb4bf-h59vq' [namespace: 'default', container: 'app', filter: '', interface: 'any']
INFO[0000] uploading static tcpdump binary from: '/root/.krew/store/sniff/v1.6.2/static-tcpdump' to: '/tmp/static-tcpdump'
INFO[0000] uploading file: '/root/.krew/store/sniff/v1.6.2/static-tcpdump' to '/tmp/static-tcpdump' on container: 'app'
INFO[0000] executing command: '[/bin/sh -c test -f /tmp/static-tcpdump]' on container: 'app', pod: 'app-prod-97dfb4bf-h59vq', namespace: 'default'
INFO[0000] command: '[/bin/sh -c test -f /tmp/static-tcpdump]' executing successfully exitCode: '0', stdErr :''
INFO[0000] file found: ''
INFO[0000] file was already found on remote pod
INFO[0000] tcpdump uploaded successfully
INFO[0000] output file option specified, storing output in: 'text.pcap'
INFO[0000] start sniffing on remote container
INFO[0000] executing command: '[/tmp/static-tcpdump -i any -U -w - ]' on container: 'app', pod: 'app-prod-97dfb4bf-h59vq', namespace: 'default'

看原理是通过本地的/tmp/static-tcpdump 文件弄到pod中去抓包

  • 17
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值