4
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

KubernetesでPodのネットワークパケットキャプチャを行う

Posted at

概要

KubernetesのPodを出入りするネットワークパケットを収集して分析する方法を紹介します。

Kubernetesでは1つのPod内に複数のコンテナを起動することができ(Sidecarと呼びます)、Pod内のコンテナは同じNICを共有します。

この仕組みを利用して、対象のPodにパケット収集用コンテナを追加し、そのコンテナの中でパケット収集処理を実行します。

スクリーンショット 2022-05-03 12.04.05.png

今回は下記の流れでパケットの収集と分析を行います。

  • パケット収集用コンテナにて、収集処理を実行して結果をファイル出力する。
  • ホストにて、kubectl cpコマンドを使って収集結果ファイルをホストにコピーする。
  • ホストにて、Wiresharkを使ってコピーしたファイルを分析する。

Wiresharkは事前にインストールしてください。

パケット収集用コンテナをPodに追加

パケット収集用コンテナに使うDockerイメージは何でも良いのですが、今回はnicolaka/netshootを使います。(ネットワーク関連の様々なコマンドがインストール済みであり、ネットワーク分析用として有名なイメージです。)

例えば下記のようなyamlファイルを作る事で、netshootという名前のパケット収集用コンテナを含むPodをDeploymentとして作成できます。

---
apiVersion: apps/v1
kind: Deployment
...
spec:
  ...:
  template:
    ...:
    spec:
      containers:
        # アプリケーションコンテナ(収集対象)
        - name: ...
          image: ...
          ...:
        # パケット収集用コンテナ
        - name: netshoot
          image: nicolaka/netshoot
          imagePullPolicy: IfNotPresent
          command: ["/bin/bash"]
          args: ["-c", "while true; do ping localhost; sleep 60; done"]

commandおよびargsの箇所では、コンテナを起動させ続けるために永続的なコマンドを実行するよう定めています。

パケットを収集

netshootコンテナを含むPodをKubernetesにデプロイしたのち、下記コマンドでnetshootコンテナにログインします。

kubectl exec <Pod名> -c netshoot -it -- /bin/bash

今回のようにPod内に複数のコンテナがある場合は、-cオプションでログインしたいコンテナの名前を指定できます。

Namespaceがdefault以外の場合は、-n <Namespace名>オプションを追加します。

ログインしたnetshootコンテナの中でifconfigコマンドを実行し、パケット収集対象のNICを探します。

ifconfig

出力結果が下記の場合は、eth0という名前のNICを対象にすれば良いとわかります。

eth0      Link encap:Ethernet  HWaddr 4E:1D:AF:72:EF:4B  
          inet addr:10.1.0.88  Bcast:10.1.255.255  Mask:255.255.0.0
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
          RX packets:19 errors:0 dropped:0 overruns:0 frame:0
          TX packets:1 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:0 
          RX bytes:1398 (1.3 KiB)  TX bytes:42 (42.0 B)

lo        Link encap:Local Loopback  
          inet addr:127.0.0.1  Mask:255.0.0.0
          UP LOOPBACK RUNNING  MTU:65536  Metric:1
          RX packets:11832 errors:0 dropped:0 overruns:0 frame:0
          TX packets:11832 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1000 
          RX bytes:993888 (970.5 KiB)  TX bytes:993888 (970.5 KiB)

loはループバック用のNICです。

アプリケーションコンテナでもifconfigコマンドが実行可能であれば、アプリケーションコンテナにログインしてifconfigコマンドを実行すると、同一のeth0というNICがある事を確認できます。

tcpdumpコマンドを実行して、パケット収集処理を起動します。

tcpdump -i eth0 -w tcpdump.out

-iオプションで対象のNICを、-wオプションで収集結果の出力先ファイル名を指定します。

パケット収集処理を起動したままの状態で、ホストからアプリケーションにアクセスして動作させます。

アプリケーションの動作が一通り完了したら、netshootコンテナの中でCtrl + Cを入力してパケット収集処理を停止します。

netshootコンテナの中でlsコマンドおよびpwdコマンドを使って、収集結果ファイルの絶対パスを確認します。

出力結果が下記の場合は、/root/tcpdump.outに収集結果ファイルがあることがわかります。

bash-5.1# ls
motd         tcpdump.out
bash-5.1# pwd
/root

収集結果を分析

ホスト側でkubectl cpコマンドを実行して、収集結果ファイルをホストにコピーします。

kubectl cp <Pod名>:/root/tcpdump.out tcpdump.out -c netshoot

-cオプションでコピー対象のコンテナを指定します。

Namespaceがdefault以外の場合は、<Namespace名>/<Pod名>:/root/tcpdump.outとします。

Wiresharkを起動し、コピーしたファイルを開くと、パケットの内容を確認できます。

スクリーンショット 2022-05-03 13.53.02.png

上記の例について、パケット分析の詳細は割愛しますが、概要は下記の通りとなります。

  • Kubernetesにはfront1とback1という2つのPodがあり、今回はfront1のパケットを収集している。
  • ホストからfront1へHTTPリクエスト
  • front1からback1へHTTPリクエスト
  • back1からfront1へHTTPレスポンス
  • front1からホストへHTTPレスポンス
4
3
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
4
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?