LoginSignup
7
1

コンテナネットワークで何かおかしい時に使える netshoot

Last updated at Posted at 2023-12-24

はじめに

Kubernetes (K8s) にデプロイされたコンテナ (Pod) のネットワークが、何かおかしい時、皆さんはどうされてますか?
kubectl exec でコンテナに入り込んで、ping を打ちたかったりしませんか?
ところが...!そのコンテナには ping はおろか、curl や ip コマンドも仕込まれていなかったり...!?

「マジかー・・・ping 仕込んだコンテナイメージ用意するかぁ・・・」とかなっていれば、ちょっと待ってください!
そんな悲しい状況下で、便利に使えるコンテナイメージがあります!

netshoot というコンテナイメージなのですが、ping はもちろん、curl や ip コマンド、はたまた iperf などのネットワークのトラブルシュートに使える様々な便利ツールが詰め込まれています。

前提

今回、直接の依存関係はありませんが、TUNA-JP Advent Calendar 2023 への寄稿ということで、強引に Tanzu に絡ませるべく、vSphere with Tanzu を使ってデプロイした TKG クラスタ上で、お試ししています。

  • vSphere 8.0 Update 2
  • kubectl v1.26.4+vmware.wcp.0
  • Kubernetes v1.25.7+vmware.3-fips.1

また、「何かおかしいな?」の題材として、下記のような nginx のコンテナを TKG クラスタ上にデプロイしています。

nginx.yaml
apiVersion: v1
kind: Service
metadata:
  name: nginx
spec:
  type: LoadBalancer
  ports:
  - port: 80
    targetPort: 80
  selector:
    app: nginx
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx
spec:
  replicas: 3
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx
        image: nginx
        imagePullPolicy: IfNotPresent
        ports:
        - containerPort: 80
$ kubectl get pods -o wide
NAME                     READY   STATUS    RESTARTS   AGE   IP           NODE                                                     NOMINATED NODE   READINESS GATES
nginx-85cf7975fb-cmrzr   1/1     Running   0          10m   10.244.1.5   project01-cluster01-node-pool-1-hsn8z-74b594979f-l8g62   <none>           <none>
nginx-85cf7975fb-fscq9   1/1     Running   0          10m   10.244.2.5   project01-cluster01-node-pool-1-hsn8z-74b594979f-thnv8   <none>           <none>
nginx-85cf7975fb-jjsfl   1/1     Running   0          10m   10.244.2.4   project01-cluster01-node-pool-1-hsn8z-74b594979f-thnv8   <none>           <none>

使い方

GitHub の README が非常に分かりやすいので、そこまで難しいことは無いと思いますが、K8s 上での使い方に関しては、Netshoot with Kubernetes のセクションを参照ください。

コンテナへのアタッチ

まず kubectl debug コマンドを使って、稼働中の nginx の Pod に netshoot のコンテナをアタッチしてみます。

$ kubectl debug nginx-85cf7975fb-cmrzr -it --image=nicolaka/netshoot
Defaulting debug container name to debugger-ggtqg.
Warning: would violate PodSecurity "restricted:latest": allowPrivilegeEscalation != false (containers "nginx", "debugger-jmvt4", "debugger-ggtqg" must set securityContext.allowPrivilegeEscalation=false), unrestricted capabilities (containers "nginx", "debugger-jmvt4", "debugger-ggtqg" must set securityContext.capabilities.drop=["ALL"]), runAsNonRoot != true (pod or containers "nginx", "debugger-jmvt4", "debugger-ggtqg" must set securityContext.runAsNonRoot=true), seccompProfile (pod or containers "nginx", "debugger-jmvt4", "debugger-ggtqg" must set securityContext.seccompProfile.type to "RuntimeDefault" or "Localhost")
If you don't see a command prompt, try pressing enter.
                    dP            dP                           dP
                    88            88                           88
88d888b. .d8888b. d8888P .d8888b. 88d888b. .d8888b. .d8888b. d8888P
88'  `88 88ooood8   88   Y8ooooo. 88'  `88 88'  `88 88'  `88   88
88    88 88.  ...   88         88 88    88 88.  .88 88.  .88   88
dP    dP `88888P'   dP   `88888P' dP    dP `88888P' `88888P'   dP

Welcome to Netshoot! (github.com/nicolaka/netshoot)
Version: 0.11




 nginx-85cf7975fb-cmrzr  ~ 

Ctrl+D や exit で、ターミナルを抜けると、自動でアタッチしたコンテナも削除してくれるので便利です。

また、プロンプトがアタッチした先の Pod 名になっているのと、Pod の IP アドレスを確認すると、ちゃんと狙った Pod の IP アドレス (前提のセクションで確認した 10.244.1.5) になっていることが確認できます。

nginx-85cf7975fb-cmrzr  ~  ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
   link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
   inet 127.0.0.1/8 scope host lo
      valid_lft forever preferred_lft forever
   inet6 ::1/128 scope host
      valid_lft forever preferred_lft forever
2: eth0@if10: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1450 qdisc noqueue state UP group default
   link/ether ee:24:6e:32:2d:dd brd ff:ff:ff:ff:ff:ff link-netnsid 0
   inet 10.244.1.5/24 brd 10.244.1.255 scope global eth0
      valid_lft forever preferred_lft forever
   inet6 fe80::ec24:6eff:fe32:2ddd/64 scope link
      valid_lft forever preferred_lft forever

ping

とりあえず、まずは ping を打ってみましょう。
外部のルータの IP アドレス 172.19.30.254 を狙ってみます。

 nginx-85cf7975fb-cmrzr  ~  ping -c 3 172.19.30.254
PING 172.19.30.254 (172.19.30.254) 56(84) bytes of data.
64 bytes from 172.19.30.254: icmp_seq=1 ttl=63 time=1.60 ms
64 bytes from 172.19.30.254: icmp_seq=2 ttl=63 time=1.10 ms
64 bytes from 172.19.30.254: icmp_seq=3 ttl=63 time=0.919 ms

--- 172.19.30.254 ping statistics ---
3 packets transmitted, 3 received, 0% packet loss, time 2003ms
rtt min/avg/max/mdev = 0.919/1.206/1.599/0.287 ms

ss (netstat)

nginx で 80番ポート (HTTP) で待ち受けているはずなので、ちゃんと Listen できているのか確認してみます。

 nginx-85cf7975fb-cmrzr  ~  ss -tupln
Netid              State               Recv-Q              Send-Q                           Local Address:Port                             Peer Address:Port              Process
tcp                LISTEN              0                   128                                    0.0.0.0:80                                    0.0.0.0:*
tcp                LISTEN              0                   128                                       [::]:80                                       [::]:*

プロセス名まで追えていない (PID Namespace が違う?) ですが、80番ポートで、何かが動いていることは確認できました。

iproute2

ルーティングのテーブルの確認のために、ip routeip neighbor コマンドを叩いてみます。

 nginx-85cf7975fb-cmrzr  ~  ip r
default via 10.244.1.1 dev eth0
10.244.1.0/24 dev eth0 proto kernel scope link src 10.244.1.5

 nginx-85cf7975fb-cmrzr  ~  ip n
10.244.1.1 dev eth0 lladdr 0e:e3:be:9c:67:2d REACHABLE

今回の環境では Antrea CNI によって管理される Open vSwitch (OVS) に渡されるので、大した情報はありませんが、「ルーティングテーブルは正しい?」などを確認する際に便利そうです。

termshark

tcpdump でも良いですが、CLI ながら Wireshark に似た UI でパケットキャプチャできる Termshark を起動しています。

 nginx-85cf7975fb-cmrzr  ~  termshark -i eth0
Termshark is initializing - please wait...
(The termshark UI will start when packets are detected on eth0...)

...(略)...

ここでは詳しくは紹介しませんが、Termshark めっちゃ便利です!びっくりしました。

iperf

もう一つ別のコンテナなり、対向してくれる端末が必要ですが、お試しで iperf を使って、スループットを計測してみます。

まず、対向する端末、例えば、もう一つ別の nginx の Pod に netshoot のコンテナをアタッチしておいて、iperf サーバーを起動しておきます。

 nginx-85cf7975fb-fscq9  ~  iperf -s
------------------------------------------------------------
Server listening on TCP port 5001
TCP window size:  128 KByte (default)
------------------------------------------------------------

...(略)...

次に、もう一方の netshoot コンテナから、iperf クライアントを実行して、スループットを計測します。

 nginx-85cf7975fb-cmrzr  ~  iperf -c 10.244.2.5
------------------------------------------------------------
Client connecting to 10.244.2.5, TCP port 5001
TCP window size: 16.0 KByte (default)
------------------------------------------------------------
[  1] local 10.244.1.5 port 40660 connected with 10.244.2.5 port 5001
[ ID] Interval       Transfer     Bandwidth
[  1] 0.00-10.12 sec   259 MBytes   214 Mbits/sec

デフォルト設定であることもあって、大して良いスループットでは無いですね...
チューニングの余地はありそうですが、ここでは割愛します。
もし、オプション指定のチューニングや、結果の集計について、ご興味があれば、下記の記事も覗いていただけると嬉しいです。

まとめ

パッとすぐに使いそうなコマンドや操作のみを取り上げましたが、netshoot には、まだまだ他にも便利なツールが同梱されています!
「あ、こんなツールあるんだ〜」と勉強になるものもあると思いますので、「いくつ知ってるかな?」気分で覗いみても面白いと思います。

7
1
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
7
1