介紹一個小工具:Ksniff

對於相當一部分讀者來說,在 Kubernetes 環境中,針對 Pod 進行抓包是個常規操作,在 Pod 中、在 Node 中都能夠完成,抓出文件之後現場查看或者拷貝回來餵給 Wireshark 也都不難。Ksniff工具的作用是,把這些常規步驟組織起來,用一個簡單的 kubectl 插件命令,就能完成這一系列的操作。

Ksniff 有幾個很有意思的特色:

  1. 可以使用 krew 方便的進行安裝。
  2. 能夠自動把 Pod 的 TCP Dump 數據輸出給 Wireshark。
  3. 能夠方便的處理非特權 Pod 的抓包工作。
  4. 無需觸碰 Node。

安裝

使用 Krew 能夠很方便的安裝 Ksniff:

$ kubectl krew install sniff
Updated the local copy of plugin index.
Installing plugin: sniff
CAVEATS:
\\
| This plugin needs the following programs:
| * wireshark (optional, used for live capture)
/
Installed plugin: sniff

抓包到 Wireshark

部署一個簡單的 httpbin 服務:

apiVersion: v1
kind: Service
metadata:
name: httpbin
labels:
app: httpbin
spec:
ports:
- name: http
port: 8000

targetPort: 80
selector:
app: httpbin
---
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
name: httpbin
spec:
replicas: 1
template:
metadata:
labels:
app: httpbin
version: v1
spec:
containers:
- image: docker.io/kennethreitz/httpbin
imagePullPolicy: IfNotPresent
name: httpbin
ports:
- containerPort: 80

服務啟動之後,再啟動一個客戶端:

apiVersion: extensions/v1beta1
kind: Deployment
metadata:
name: sleep
spec:
replicas: 1
template:
metadata:
labels:
app: sleep
version: v1
spec:
containers:
- name: sleep
image: dustise/sleep
imagePullPolicy: IfNotPresent

然後就可以啟動 ksniff 插件來對 httpbin 的 Pod 進行監聽了,例如:

$ kubectl sniff httpbin-5fc7cf895d-lr89b 

...
INFO[0000] sniffing method: upload static tcpdump
...
INFO[0000] using tcpdump path at: '/Users/dustise/.krew/store/sniff/
。。。INFO[0002] executing command: '[/tmp/static-tcpdump -i any -U -w - ]' on container: 'httpbin', pod: 'httpbin-5fc7cf895d-lr89b', namespace: 'default'

不難看出,ksniff 非常粗暴的將一個 tcpdump 上傳到了被抓包的 Pod 上直接運行。並且命令執行後,直接啟動了 Wireshark 進行監聽。

下面從 sleep Pod 上給被監聽 Pod 製造一點流量。

$ kubectl exec -it sleep-69bd44b5bb-tk6vn -- curl http://httpbin:8000/ip
{
"origin": "10.244.0.19"
}

在 Wireshark 中會看到相應的數據包:

介紹一個小工具:Ksniff

Wireshark

查看一下被監聽 Pod 的進程:

$ kubectl exec -it httpbin-5fc7cf895d-lr89b -- ps aux
USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND
root 1 0.0 0.6 85980 25100 ? Ss 15:42 0:01 /usr/bin/python
root 8 0.0 0.8 130364 35164 ? S 15:42 0:01 /usr/bin/python
root 35 0.0 0.0 6392 3568 ? Ss 15:50 0:00 /tmp/static-tcp
root 47 0.0 0.0 6392 3564 ? Ss 15:58 0:00 /tmp/static-tcp
root 70 0.0 0.0 6392 3564 ? Ss 16:17 0:00 /tmp/static-tcp
root 90 0.0 0.0 6392 3568 ? Ss 17:01 0:00 /tmp/static-tcp
root 102 0.0 0.0 6392 3568 ? Ss 17:05 0:00 /tmp/static-tcp

不難看到,多出了幾個 /tmp/static-tcp 的進程。

無特權 Pod 怎麼辦

Ksniff 還提供了 -p 參數,用於針對無特權 Pod 進行監聽。帶有這一參數之後,查詢目標 Pod 所在節點,然後在該節點上利用節點親和性創建共享節點網絡的特權 Pod,然後在新 Pod 上對流量進行監控。

$ kubectl sniff httpbin-5fc7cf895d-lr89b -p 1.1 ✱
INFO[0000] sniffing method: privileged pod
INFO[0000] using tcpdump path at: '/Users/dustise/.krew/store/sniff/71102253eded8900c8f7b0d0624c65b3c77ecd6bcd28fabc9a200da
ac502282a/static-tcpdump'
INFO[0000] no container specified, taking first container we found in pod.
INFO[0000] selected container: 'httpbin'
...
INFO[0000] creating privileged pod on node: 'vla'
...
INFO[0008] pod: 'ksniff-qpznn' created successfully on node: 'vla'
$ kubectl get pods
flaskapp-v1-5f58cbc685-9v4z9 1/1 Running 0 92m
httpbin-5fc7cf895d-lr89b 1/1 Running 0 93m
ksniff-689sx 1/1 Running 0 66m
sleep-69bd44b5bb-tk6vn 1/1 Running 0 93m

可以看到,ksniff 創建了新的 Pod。並且也成功的啟動了 Wireshark。再次執行:

$ kubectl exec -it sleep-69bd44b5bb-tk6vn -- curl http://httpbin:8000/ip
{
"origin": "10.244.0.19"
}

可以看到,Wireshark 中出現了新的數據包。

參考鏈接

  • https://github.com/kubernetes-sigs/krew
  • https://github.com/eldadru/ksniff


分享到:


相關文章: