はじめに
Kubernetes で ksniff を使ってパケットキャプチャをする方法を紹介します。
ksniff
ksniff は、tcpdump と Wireshark でのパケットキャプチャができる kubectl プラグインです。
tcpdump のバイナリをコンテナに追加、もしくは別の Pod から tcpdump でパケットキャプチャし、その結果をローカルの Wireshark に送ってくれます。
ksniff はまだ production ready ではないので、本番環境での動作はおすすめしないみたいです。なので、開発用の環境やローカルで検証する時に使うツールとして考えるのが良さそうです。
インストール
krew
を使って、インストールできます。
kubectl krew install sniff
krew
については、下記を参考にしてください。

使い方
基本的な使い方は下記の通りです。
kubectl sniff <POD_NAME> [-n <NAMESPACE_NAME>] [-c <CONTAINER_NAME>] [-i <INTERFACE_NAME>] [-f <CAPTURE_FILTER>] [-o OUTPUT_FILE] [-l LOCAL_TCPDUMP_FILE] [-r REMOTE_TCPDUMP_FILE]
non-privileged ユーザーで実行している Pod は、-p
をつけると、別の Pod を作成し、そこから特権モードでキャプチャしてくれます。
試してみる
試しに下記のサンプルアプリでパケットキャプチャしてみます。
❯ kubectl get pod
NAME READY STATUS RESTARTS AGE
details-v1-698d88b-wl7jh 2/2 Running 0 7m7s
productpage-v1-675fc69cf-nrmth 2/2 Running 0 7m6s
ratings-v1-6484c4d9bb-db29m 2/2 Running 0 7m7s
reviews-v1-5b5d6494f4-6rr5c 2/2 Running 0 7m6s
reviews-v2-5b667bcbf8-22hn6 2/2 Running 0 7m6s
reviews-v3-5b9bd44f4-m5qsh 2/2 Running 0 7m6s
ksniff を実行します。
❯ kubectl sniff productpage-v1-675fc69cf-nrmth -n default -c productpage -p
INFO[0000] sniffing method: privileged pod
INFO[0000] sniffing on pod: 'productpage-v1-675fc69cf-nrmth' [namespace: 'default', container: 'productpage', filter: '', interface: 'any']
INFO[0000] creating privileged pod on node: 'docker-desktop'
INFO[0000] pod: 'ksniff-nmsc7' created successfully in namespace: 'default'
INFO[0000] waiting for pod successful startup
INFO[0003] pod: 'ksniff-nmsc7' created successfully on node: 'docker-desktop'
INFO[0003] spawning wireshark!
...
実行すると、Wireshark が起動して、パケットの確認ができます。
Pod も確認してみると、ksniff の Pod が起動していることが確認できます。
❯ kubectl get pod
NAME READY STATUS RESTARTS AGE
details-v1-698d88b-wl7jh 2/2 Running 0 12m
ksniff-nmsc7 2/2 Running 0 2m26s
productpage-v1-675fc69cf-nrmth 2/2 Running 0 12m
ratings-v1-6484c4d9bb-db29m 2/2 Running 0 12m
reviews-v1-5b5d6494f4-6rr5c 2/2 Running 0 12m
reviews-v2-5b667bcbf8-22hn6 2/2 Running 0 12m
reviews-v3-5b9bd44f4-m5qsh 2/2 Running 0 12m
エラー
使っている時にいくつかエラーに遭遇したので、解決策とともに紹介します。
Error: exec: "wireshark": executable file not found in $PATH
まずは、下記のエラーです。
...
Error: exec: "wireshark": executable file not found in $PATH
こちらは、下記の Issue で解決されていました。
解決方法としては、/usr/local/bin
にwireshark
のスクリプトを作成する必要があります。
まずは、/usr/local/bin
にwireshark
を作成します。
cd /usr/local/bin/
sudo vim wireshark
wireshark
の内容は下記の通りです。
#!/usr/bin/env bash
WIRESHARK="/Applications/Wireshark.app/Contents/MacOS/Wireshark"
${WIRESHARK} "$@"
exit $?
作成したら、実行権限をつけて完了です。
cd /usr/local/bin/
chmod a+x wireshark
failed to start remote sniffing, stopping wireshark error="executing sniffer failed, exit code: '1'"
次は、下記のエラーです。
...
INFO[0000] start sniffing on remote container
INFO[0000] executing command: '[/tmp/static-tcpdump -i any -U -w - ]' on container: 'productpage', pod: 'productpage-v1-6c4f8467b9-5bb9p', namespace: 'default'
INFO[0000] command: '[/tmp/static-tcpdump -i any -U -w - ]' executing successfully exitCode: '1', stdErr :'static-tcpdump: any: You don't have permission to capture on that device
(socket: Operation not permitted)
'
ERRO[0000] failed to start remote sniffing, stopping wireshark error="executing sniffer failed, exit code: '1'"
INFO[0000] starting sniffer cleanup
INFO[0000] sniffer cleanup completed successfully
Error: signal: killed
こちらは、下記の Issue でも質問されていますが、私の場合は-p
オプションをつけることで解決できました。
kubectl sniff -p <POD_NAME>