Red HatのNFVPEというチームに所属しています林(と)1と申します。
赤帽エンジニアAdvent Calendar 2018の18日目の本記事では12/10-13日に行なわれましたKubeCon + CloudNativeCon North America 2018(KubeCon NA 2018)で発表した"Troubleshooting On-Premise Kubernetes Network: Underlay, Overlay and Pod"についてご紹介致します。ちなみに発表のスライドはこのページの下の方にpdfがあります。
話の主な内容
主にオンプレミス環境でKubernetes(またはOpenShift)を運用する際に問題となるようなネットワークのトラブルシューティングについての始めの一歩として
- インストール時に出やすいエラーとその対処
- Podのインターフェイスの情報の取得
- Podのトラフィックをタッピング
の3点を説明しました。本日はその中で紹介したPodのトラフィックをキャプチャするにはどうすればいいかについて説明します。
Podのトラフィックをタッピングするにはどうすればいいか?
ネットワークのトラブルで多く使われるトラブルシューティングの一つにパケットのキャプチャがあります。Kubernetesではiptablesを多用するために、各所でヘッダの内容が異なるため、デバッグする際にはそのケース毎にキャプチャしたい箇所はノードのインターフェースだったり、(ovsを含む)bridgeだったりと異なると思います。
その中でもPod内部のインターフェイス(=eth0)をキャプチャするのは非常にやっかいです。なぜかというと以下の理由があります。
- コンテナイメージにwireshark等のソフトがインストールされているケースがほぼ無い
- よしんば入っていたとしてもPodのPrivilegeによってwiresharkの実行ができない
現在ですと以下の手順を踏んでnsenterコマンドを用いることでパケットのキャプチャが可能ですがこれもまた手数の多さが問題となります。
kubectl get pod <pod名> -o json
等で対象のPodの動作しているノード、ContainerIDを確認する- 対象のノードで
docker inspect
やcrictl inspect
コマンドを実行してPIDを取得する - 対象のノードにwiresharkをインストールする(インストールされていない場合)
sudo nseneter -t <pid> -n -- wireshark
でキャプチャする
そこでkokotapというソフトを開発しました。 このソフトでは対象のPodのインターフェイスをLinuxのtc-mirred という機能を使ってミラーを行ない、 VxLANで他のノードに飛ばすことを行ないます。
例えば以下のようなコマンドを実行するとPod(centos)のトラフィックをミラーする'mirror'インターフェイスをkube-masterに作成することが可能です。これでコンテナにソフトが入っていなくてもパケットをキャプチャすることが可能になります。
[centos@kube-master ~]$ ./kokotap --pod=centos --mirrortype=both \ --dest-node=kube-master --vxlan-id=100 | kubectl create -f - pod/kokotap-centos-sender created pod/kokotap-centos-receiver-kube-master created [centos@kube-master ~]$ ip a 1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN qlen 1 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 (snip) 17: mirror: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1450 qdisc noqueue state UNKNOWN qlen 1000 link/ether 7e:3a:cb:bf:95:28 brd ff:ff:ff:ff:ff:ff inet6 fe80::7c3a:cbff:febf:9528/64 scope link valid_lft forever preferred_lft forever
また対象のホストをIPアドレスで指定することでKubernetesの管理対象になっていないノードにもミラーのトラフィックを飛ばすことが可能です。この場合は受信側のVxLANインターフェイスを自分で作成する必要があります。
ミラー(送信側)作成
[centos@kube-master ~]$ ./kokotap --pod=centos --mirrortype=both \ --dest-ip=10.1.1.1 --vxlan-id=100 | kubectl create -f - pod/kokotap-centos-sender created pod/kokotap-centos-receiver-kube-master created
ミラー(受信側)作成
[centos@10.1.1.1 ~]$ sudo ip link add mirror type vxlan id 192.168.1.1 dev eth0 dstport 4789 [centos@10.1.1.1 ~]$ sudo ip link set up mirror [centos@10.1.1.1 ~]$ wireshark -i mirror
デモ動画
以下の動画で上のコマンドの実行例が確認できます。
kokotap demo movie at KubeConNA 2018
まとめ
本記事ではKubeCon 2018 NAで発表した"Troubleshooting On-Premise Kubernetes Network: Underlay, Overlay and Pod"の中のPodのトラフィックをキャプチャするにはどうすればいいかを紹介しました。 Kubernetesを使ったさいのアプリケーションのデバッグやネットワークのデバッグの助けとなれば幸いです。
-
弊社には同姓の社員がいるのでとりあえずこんな形で区別してみました。↩