最无侵入的抓包方式是用nsenter进入目标进程netns:不改镜像、不重启服务、复用宿主机tcpdump,仅需获取PID并以root权限执行nsenter -n -t tcpdump。

直接用 nsenter -n -t [PID] tcpdump 就能穿透到目标进程的 Network Namespace 抓包,不需要进容器、不依赖 Docker 或 Kubernetes 运行时,核心在于拿到进程 PID 并确保有权限访问其网络命名空间。
第一步:准确获取目标进程的 PID
不同运行时获取方式略有差异,关键是要拿到宿主机视角下的真实 PID:
- Docker 容器:执行
docker inspect --format='{{.State.Pid}}' <container_id_or_name></container_id_or_name> - containerd(K8s 常见):先用
kubectl get pod -o wide查节点和 IP,登录对应节点后运行crictl ps -a | grep <pod_name></pod_name>获取 container ID,再执行crictl inspect <container_id> | grep -i pid</container_id> - 纯 systemd 服务或自定义进程:可用
pgrep -f "your_service_cmd"或ps aux | grep your_process
第二步:验证该 PID 确实拥有独立 netns
检查 /proc/[PID]/ns/net 是否存在且非指向宿主机默认命名空间:
- 运行
ls -l /proc/[PID]/ns/net,输出类似net:[4026532567]表示有效隔离 - 对比宿主机 netns:
ls -l /proc/1/ns/net,编号不同即确认隔离成立 - 若提示
Permission denied,需以 root 或具备CAP_SYS_ADMIN权限的用户操作
第三步:进入 netns 并执行抓包
最常用且安全的方式是只进入网络命名空间,复用宿主机工具:
- 基础抓包:
nsenter -n -t [PID] tcpdump -i eth0 -w /tmp/capture.pcap - 带过滤条件:
nsenter -n -t [PID] tcpdump -i any port 8080 -c 100 - 实时查看 + 保存:
nsenter -n -t [PID] tcpdump -i eth0 -v -s 0 -w - | wireshark -k -i -(需宿主机装 Wireshark) - 如需同时看路由或接口状态,可先进入交互式 shell:
nsenter -n -t [PID] bash,再运行ip route、ss -tuln等辅助诊断
注意事项与常见问题
实际使用中容易卡在权限或路径细节上:
- 必须用 root 执行 nsenter,普通用户即使加 sudo 也可能因 /proc/[PID]/ns/ 权限受限失败
- 不要加
-m(挂载命名空间)除非真要访问容器内文件系统——加了反而可能找不到tcpdump路径或挂载点异常 - 若容器用 hostNetwork 模式,其 netns 与宿主机相同,抓包结果会混杂所有流量,需结合
tcpdump -i docker0或bridge接口区分 - 某些精简镜像(如 distroless)虽无 shell,但只要进程在运行、netns 存在,nsenter 就依然可用











