Kubernetes 容器内部如何捉 tcpdump
与普通场景下捉 tcpdump 不一样,部署在容器内部的应用程序无法直接在服务器上捉取流量。捕获应用程序流量要相对麻烦。
Sidecar
该方法 tcpdump 以容器的形式与应用程序共同运行。由于 Kubernetes 的多个 container 处于同一 network namespace,所以处于不同容器中的 tcpdump 可以捕获同一个 Pod 内的不同 container 的流量。
优点:通用性强
缺点:会导致 Pod 重启
例子
下方的 Yaml 文件中,定义了一个 Pod 和 一个 Service。
Pod 中有两个容器——httpbin 和 tcpdump。httpbin 是一款开源的 HTTP 测试程序,可用来接收请求和返回特定行为的响应,用于模拟应用程序。tcpdump 用于捕获流量。
这里我直接使用同行已经做好的 corfr/tcpdump 镜像。该镜像会 /data/ 目录下生成 tcpdump 文件。tcpdump 具体的行为可以参考 Dockerfile https://github.com/CoRfr/tcpdump-docker/blob/master/Dockerfile.
而 Service 用于暴露 httpbin,方便发起 HTTP 请求。
apiVersion: v1
kind: Pod
metadata:
name: tcpdump-demo
labels:
app: tcpdump-demo
spec:
containers:
- name: httpbin
image: kennethreitz/httpbin
ports:
- containerPort: 80
- name: tcpdump
image: corfr/tcpdump
---
apiVersion: v1
kind: Service
metadata:
name: tcpdump-demo
labels:
app: tcpdump-demo
spec:
ports:
- port: 80
protocol: TCP
selector:
app: tcpdump-demo
type: NodePort
你可以通过执行 curl 命令,触发一段测试流量。
curl http://<node-ip>:<node-port>/get
然后,执行如下命令把流量文件拷贝出来,在 Wireshark 等软件中打开。
kubectl cp tcpdump-demo:/data/dump00 ./dump00 -c tcpdump
Worker Node
外部流量流入 Pod 前,必须经过 worker node。也就是说,在 worker node 上也可以捕获应用流量。
优点:可以捕获 Pod 启动前的流量
缺点:可能需要指定端口、网卡以避免捕获过多的流量。而查询端口、网卡操作比较麻烦。另外 worker node 上也未必有/允许安装 tcpdump。
tcpdump -C 1000 -W 100 -v -w dump.cap
容器内部执行 tcpdump 命令
直接 kubectl exec -it ...-- bash
进容器,以普通方法执行 tpcdump 命令也是一个可选的方法(大概)。
优点:可以避免容器重启丢失现场
缺点:我不觉得成熟的生产环境应用会开放 root 权限安装 tcpdump...
zypper in -y tcpdump # 或者通过其他系统的包管理工具安装 tcpdump
tcpdump -C 1000 -W 100 -v -w /tmp/dump.cap
之后把流量文件复制出来
kubectl cp tcpdump-demo:/tmp/dump.cap ./dump.cap